<?php

namespace App\Console\Commands;

use App\Services\AutoTraderAIApi;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Mtc\AutoTraderStock\Services\AutoTraderService;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;

class AutoTraderMatchStockIds extends Command
{
    protected $signature = 'auto-trader:match-stock-ids
                            {--dry-run : Report without updating auto_trader_id values}';

    protected $description = 'Reconcile AutoTrader stock against local vehicles, '
        . 'matching by VRM/VIN and updating auto_trader_id. '
        . 'Reports stock present on AutoTrader but not in local inventory. '
        . 'Run via `artisan tenants:run auto-trader:match-stock-ids` for tenant context.';

    private const SKIPPED_LIFECYCLE_STATES = ['WASTEBIN', 'DELETED'];

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

        $locations = $this->loadAutoTraderLocations();
        if ($locations->isEmpty()) {
            $this->line('  No dealerships with auto-trader-location-id configured. Skipping.');
            return Command::SUCCESS;
        }

        $api = App::make(AutoTraderAIApi::class);
        $dryRun = (bool) $this->option('dry-run');
        $stats = ['matched' => 0, 'updated' => 0];
        $unmatched = collect();

        foreach ($locations as $locationId) {
            $service = new AutoTraderService($locationId, $api);
            $stock = $service->fetchVehicles()
                ->reject(fn ($v) => in_array(
                    $v['metadata']['lifecycleState'] ?? null,
                    self::SKIPPED_LIFECYCLE_STATES,
                    true
                ));

            foreach ($stock as $atVehicle) {
                $vehicle = $this->findLocalVehicle($atVehicle);
                if ($vehicle === null) {
                    $unmatched->push($this->unmatchedRow($atVehicle));
                    continue;
                }

                $stats['matched']++;
                $stockId = $atVehicle['metadata']['stockId'] ?? null;
                if ($stockId && $vehicle->auto_trader_id !== $stockId) {
                    if (!$dryRun) {
                        $vehicle->update(['auto_trader_id' => $stockId]);
                    }
                    $stats['updated']++;
                }
            }
        }

        $this->line(sprintf(
            '  Matched: %d, Updated: %d%s, Unmatched (AutoTrader-only): %d',
            $stats['matched'],
            $stats['updated'],
            $dryRun ? ' (dry-run, not persisted)' : '',
            $unmatched->count()
        ));

        if ($unmatched->isNotEmpty()) {
            $this->newLine();
            $this->line('  Vehicles on AutoTrader with no local match:');
            $this->table(
                ['AT ID', 'VIN', 'VRM', 'Make', 'Model', 'Derivative', 'Price'],
                $unmatched->toArray()
            );
        }

        return Command::SUCCESS;
    }

    private function loadAutoTraderLocations(): Collection
    {
        return Dealership::all()
            ->map(fn (Dealership $d) => $d->data['auto-trader-location-id'] ?? null)
            ->filter()
            ->unique()
            ->values();
    }

    private function findLocalVehicle(array $atVehicle): ?Vehicle
    {
        $vrm = $atVehicle['vehicle']['registration'] ?? null;
        $vin = $atVehicle['vehicle']['vin'] ?? null;

        if (!empty($vrm)) {
            $byVrm = Vehicle::query()->where('vrm_condensed', $vrm)->first();
            if ($byVrm) {
                return $byVrm;
            }
        }

        if (!empty($vin)) {
            return Vehicle::query()->where('vin', $vin)->first();
        }

        return null;
    }

    private function unmatchedRow(array $atVehicle): array
    {
        $price = $atVehicle['adverts']['retailAdverts']['totalPrice']['amountGBP']
            ?? $atVehicle['adverts']['retailAdverts']['suppliedPrice']['amountGBP']
            ?? null;

        return [
            $atVehicle['metadata']['stockId'] ?? '',
            $atVehicle['vehicle']['vin'] ?? '',
            $atVehicle['vehicle']['registration'] ?? '',
            $atVehicle['vehicle']['make'] ?? '',
            $atVehicle['vehicle']['model'] ?? '',
            $atVehicle['vehicle']['derivative'] ?? '',
            $price !== null ? number_format((float) $price, 2, '.', '') : '',
        ];
    }
}
