<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;

class CleanupDuplicateMotorsDealerships extends Command
{
    protected $signature = 'motors:cleanup-duplicate-dealerships
                            {--dry-run : Report what would change without writing}';

    protected $description = 'Merge duplicate dealerships sharing the same motors-location-id. '
        . 'Reassigns vehicles to a single canonical dealership per location and deletes duplicates. '
        . 'Run via `artisan tenants:run motors:cleanup-duplicate-dealerships` for tenant context.';

    public function handle(): int
    {
        $this->line('Tenant: ' . tenant('id'));

        $duplicateGroups = $this->findDuplicateGroups();

        if ($duplicateGroups->isEmpty()) {
            $this->line('  No duplicate dealerships found.');
            return Command::SUCCESS;
        }

        $dryRun = (bool) $this->option('dry-run');

        $stats = ['groups' => 0, 'duplicates_removed' => 0, 'vehicles_reassigned' => 0];

        foreach ($duplicateGroups as $motorsLocationId => $count) {
            $dealerships = Dealership::query()
                ->where('data->motors-location-id', (string) $motorsLocationId)
                ->orderBy('id')
                ->get();

            if ($dealerships->count() < 2) {
                continue;
            }

            $canonical = $dealerships->shift();
            $duplicateIds = $dealerships->pluck('id')->all();

            $vehicleCount = Vehicle::query()
                ->whereIn('dealership_id', $duplicateIds)
                ->count();

            $this->line(sprintf(
                '  motors-location-id=%s: keep %s, merge %d duplicate(s), reassign %d vehicle(s)',
                $motorsLocationId,
                $canonical->id,
                count($duplicateIds),
                $vehicleCount
            ));

            if (!$dryRun) {
                Vehicle::query()
                    ->whereIn('dealership_id', $duplicateIds)
                    ->update(['dealership_id' => $canonical->id]);

                Dealership::query()
                    ->whereIn('id', $duplicateIds)
                    ->delete();
            }

            $stats['groups']++;
            $stats['duplicates_removed'] += count($duplicateIds);
            $stats['vehicles_reassigned'] += $vehicleCount;
        }

        $this->newLine();
        $this->line(sprintf(
            '  %sGroups: %d, Duplicates removed: %d, Vehicles reassigned: %d',
            $dryRun ? '[dry-run] ' : '',
            $stats['groups'],
            $stats['duplicates_removed'],
            $stats['vehicles_reassigned']
        ));

        return Command::SUCCESS;
    }

    private function findDuplicateGroups(): \Illuminate\Support\Collection
    {
        return Dealership::query()
            ->whereNotNull('data')
            ->get(['id', 'data'])
            ->map(fn (Dealership $dealership) => $dealership->data['motors-location-id'] ?? null)
            ->filter()
            ->countBy()
            ->filter(fn (int $count) => $count > 1);
    }
}
