<?php

namespace Tests\Tenant;

use App\Events\NewVehicleImported;
use App\Events\VehicleUpdatedFromImport;
use App\Imports\AutoGrabToVehicleImport;
use App\Services\AutoGrab\AutoGrabFeedImporter;
use App\Services\AutoGrab\AutoGrabFeedRowMapper;
use Illuminate\Support\Facades\Event;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class AutoGrabFeedImportTest extends TenantTestCase
{
    /**
     * A row shaped like the 26-column AutoGrab feed schema (no images / transmission / listing
     * sources / tag_ids — the file omits those).
     */
    private function row(array $overrides = []): array
    {
        return array_merge([
            'id' => 'ag-1',
            'vehicle_id' => 100,
            'rego' => 'AB12CDE',
            'vin' => 'SALVIN000000000001',
            'vehicle_title' => 'Land Rover Defender 110',
            'make' => 'Land Rover',
            'model' => 'Defender',
            'badge' => 'HSE',
            'series' => 'L663',
            'year' => 2020,
            'release_year' => 2020,
            'color' => 'Santorini Black',
            'fuel_type' => 'Diesel',
            'body_type' => 'SUV',
            'capacity_cc' => 2999,
            'num_seats' => 5,
            'num_doors' => 5,
            'power_kw' => 147,
            'vehicle_rrp' => 60000,
            'kms' => 25000,
            'price' => 45000,
            'postcode' => 'AB1 2CD',
            'contact_name' => 'Example Dealer',
            'updated_at' => '2026-07-01 06:00:00',
            'listed_at' => '2026-06-01 06:00:00',
            'removed_at' => null,
        ], $overrides);
    }

    public function testRowMapperSuppliesSafeDefaultsForOmittedColumns(): void
    {
        $lead = new AutoGrabFeedRowMapper()->toLead(['id' => 'ag-9', 'rego' => 'AB12CDE']);

        // tag_ids MUST default to [] — AutoGrabToVehicleImport::add() runs in_array() on it.
        $this->assertSame([], $lead['tag_ids']);
        $this->assertArrayHasKey('seller_type', $lead);
        $this->assertNull($lead['seller_type']);
        $this->assertSame([], $lead['listing_sources']);
        // Original columns are preserved.
        $this->assertSame('ag-9', $lead['id']);
        $this->assertSame('AB12CDE', $lead['rego']);
    }

    public function testImportBatchCreatesVehicleWithoutImages(): void
    {
        Event::fake([NewVehicleImported::class, VehicleUpdatedFromImport::class]);

        $stats = new AutoGrabFeedImporter()->importBatch([$this->row()]);

        $this->assertSame(1, $stats['processed']);
        $this->assertSame(0, $stats['failed']);

        $vehicle = Vehicle::query()
            ->where('stock_provider', 'autograb')
            ->where('uuid', 'ag-1')
            ->first();

        $this->assertNotNull($vehicle);
        // The Vehicle model normalises UK plates (e.g. "AB12 CDE"); compare condensed.
        $this->assertSame('AB12CDE', str_replace(' ', '', (string) $vehicle->registration_number));
        $this->assertEquals(45000, $vehicle->price);
        $this->assertTrue((bool) $vehicle->was_recently_synced);
        // The feed carries no imagery, so no media uses are created.
        $this->assertSame(0, $vehicle->mediaUses()->count());
    }

    public function testImportBatchUpdatesExistingVehicleAndClearsPendingFlag(): void
    {
        Event::fake([NewVehicleImported::class, VehicleUpdatedFromImport::class]);

        // Simulate the provider having marked this in-feed vehicle pending before dispatch.
        Vehicle::factory()->create([
            'stock_provider' => 'autograb',
            'uuid' => 'ag-1',
            'registration_number' => 'AB12CDE',
            'price' => 45000,
            'was_recently_synced' => false,
            'pending_stock_sync' => 1,
        ]);

        $stats = new AutoGrabFeedImporter()->importBatch([$this->row(['price' => 42000])]);

        $this->assertSame(1, $stats['processed']);
        $this->assertSame(1, Vehicle::query()->where('uuid', 'ag-1')->count());

        $vehicle = Vehicle::query()->where('uuid', 'ag-1')->first();
        $this->assertEquals(42000, $vehicle->price);
        $this->assertTrue((bool) $vehicle->was_recently_synced);
        $this->assertNull($vehicle->pending_stock_sync);
    }

    public function testDeactivateNotRecentlySyncedRemovesOnlyUnsyncedUnpendingVehicles(): void
    {
        Event::fake();

        // Synced this run -> kept.
        $synced = Vehicle::factory()->create([
            'stock_provider' => 'autograb',
            'uuid' => 'keep-synced',
            'was_recently_synced' => true,
            'pending_stock_sync' => null,
        ]);
        // Absent from the snapshot -> removed.
        $absent = Vehicle::factory()->create([
            'stock_provider' => 'autograb',
            'uuid' => 'drop-absent',
            'was_recently_synced' => false,
            'pending_stock_sync' => null,
        ]);
        // Still queued for an async batch -> protected.
        $pending = Vehicle::factory()->create([
            'stock_provider' => 'autograb',
            'uuid' => 'keep-pending',
            'was_recently_synced' => false,
            'pending_stock_sync' => 1,
        ]);
        // A different provider -> untouched.
        $other = Vehicle::factory()->create([
            'stock_provider' => 'motors',
            'uuid' => 'other-provider',
            'was_recently_synced' => false,
            'pending_stock_sync' => null,
        ]);

        $removed = new AutoGrabToVehicleImport()->deactivateNotRecentlySynced();

        $this->assertSame(1, $removed);
        $this->assertNotNull(Vehicle::query()->whereKey($synced->id)->first());
        $this->assertNull(Vehicle::query()->whereKey($absent->id)->first());
        $this->assertNotNull(Vehicle::withTrashed()->whereKey($absent->id)->first());
        $this->assertNotNull(Vehicle::query()->whereKey($pending->id)->first());
        $this->assertNotNull(Vehicle::query()->whereKey($other->id)->first());
    }
}
