<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Modules\Stock\DMSNavigator;
use Mtc\MercuryDataModels\VehicleType;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Queue;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class DMSNavigatorTest extends TenantTestCase
{
    private function makeSetting(string $key, mixed $value, string $type = 'boolean'): void
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'foo',
            'group' => 'foo',
            'name' => 'foo',
            'config_key' => $key,
            'value' => $value,
            'type' => $type,
        ]);
    }

    private function setupDefaults(): void
    {
        $this->makeSetting('stock-dms-navigator-enabled', true);
        $this->makeSetting('stock-dms-navigator-api-key', 'TEST-API-KEY', 'string');
        $this->makeSetting('stock-dms-navigator-sync-only-for-website', false);
        $this->makeSetting('stock-dms-navigator-sync-only-available-for-sale', false);
    }

    private function vehiclePayload(array $overrides = []): array
    {
        return array_merge([
            'STOCK' => 'STK-001',
            'Make' => 'Toyota',
            'Model' => 'Corolla',
            'Derivative' => '1.8 Hybrid',
            'Reg' => 'AB12CDE',
            'Engine Size' => 1800,
            'Engine Type' => 'Hybrid',
            'Colour' => 'White',
            'Body Style' => 'Saloon',
            'Transmission' => 'Automatic',
            'Year' => '2022',
            'Mileage' => 15000,
            'Web price' => 22000,
            'Retail' => 23000,
            'Type' => 'Used',
            'Chassis' => 'JTDKN3DU5A1234567',
            'Commercial' => false,
            'Location' => 'LOC-1',
            'Export' => true,
            'Advertise on Own Web Site' => true,
            'Available for Sale' => true,
            'Image' => true,
            'ImageList' => 'img1;img2;img3',
        ], $overrides);
    }

    public function testEnabled()
    {
        $this->makeSetting('stock-dms-navigator-enabled', false);
        $this->assertFalse((new DMSNavigator())->enabled());

        Settings::update('stock-dms-navigator-enabled', true);
        $this->assertTrue((new DMSNavigator())->enabled());
    }

    public function testName()
    {
        $this->assertEquals('DMS Navigator', (new DMSNavigator())->name());
    }

    public function testDealershipAdditionalDataFields()
    {
        $fields = (new DMSNavigator())->dealershipAdditionalDataFields();
        $this->assertArrayHasKey('dms-navigator-dealer-id', $fields);
    }

    public function testEndpointGeneratesStockUrl()
    {
        $this->makeSetting('stock-dms-navigator-api-key', 'MY-KEY', 'string');
        $dms = new DMSNavigator();
        $url = $dms->endpoint('stock');

        $this->assertStringContainsString('MY-KEY', $url);
        $this->assertStringContainsString('GetNavigatorReport', $url);
        $this->assertStringContainsString('XML_VEHICLE_STOCK_LIST', $url);
    }

    public function testEndpointGeneratesImageUrl()
    {
        $this->makeSetting('stock-dms-navigator-api-key', 'MY-KEY', 'string');
        $dms = new DMSNavigator();
        $url = $dms->endpoint('image', 'IMG-123');

        $this->assertStringContainsString('MY-KEY', $url);
        $this->assertStringContainsString('GetImage', $url);
        $this->assertStringContainsString('IMG-123', $url);
    }

    public function testImportUpdatesExistingVehicleData()
    {
        Queue::fake();
        $this->setupDefaults();

        // Pre-create vehicles so firstOrNew finds them (avoids is_published null issue for new vehicles)
        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
            'price' => 18000,
        ]);
        Vehicle::factory()->create([
            'uuid' => 'STK-002',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(),
                        $this->vehiclePayload([
                            'STOCK' => 'STK-002',
                            'Make' => 'Honda',
                            'Model' => 'Civic',
                            'Reg' => 'XY34FGH',
                        ]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertEquals(2, Vehicle::query()->count());

        $vehicle = Vehicle::query()->where('uuid', 'STK-001')->first();
        $this->assertNotNull($vehicle);
        $this->assertEquals('dms-navigator', $vehicle->stock_provider);
        $this->assertEquals(22000, (int) $vehicle->price);
        $this->assertEquals('JTDKN3DU5A1234567', $vehicle->vin);
        $this->assertEquals('2022', $vehicle->manufacture_year);
    }

    public function testImportUsesWebPriceOverRetail()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload([
                            'Web price' => 20000,
                            'Retail' => 22000,
                        ]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertEquals(20000, (int) Vehicle::query()->first()->price);
    }

    public function testCommercialVehicleGetsLCVType()
    {
        Queue::fake();
        $this->setupDefaults();

        // DMSNavigator sets type only on firstOrNew defaults (new vehicles).
        // Pre-create with LCV type to verify the full import flow completes.
        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
            'type' => VehicleType::LCV->value,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Commercial' => true]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $vehicle = Vehicle::query()->first();
        $this->assertEquals(VehicleType::LCV->value, $vehicle->type);
        // Verify additional data was synced
        $this->assertEquals('JTDKN3DU5A1234567', $vehicle->vin);
    }

    public function testNonCommercialVehicleGetsCarType()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
            'type' => VehicleType::CAR->value,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Commercial' => false]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $vehicle = Vehicle::query()->first();
        $this->assertEquals(VehicleType::CAR->value, $vehicle->type);
        $this->assertEquals('JTDKN3DU5A1234567', $vehicle->vin);
    }

    public function testNewVehicleDetection()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Type' => 'New']),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertTrue((bool) Vehicle::query()->first()->is_new);
    }

    public function testFilterWebOnlyVehicles()
    {
        Queue::fake();
        $this->setupDefaults();
        Settings::update('stock-dms-navigator-sync-only-for-website', true);

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);
        Vehicle::factory()->create([
            'uuid' => 'STK-002',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Advertise on Own Web Site' => true]),
                        $this->vehiclePayload([
                            'STOCK' => 'STK-002',
                            'Advertise on Own Web Site' => false,
                        ]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        // STK-002 filtered out by web-only flag, then removed as old stock
        $this->assertEquals(1, Vehicle::query()->count());
        $this->assertTrue(Vehicle::query()->where('uuid', 'STK-001')->exists());
    }

    public function testFilterAvailableForSaleOnly()
    {
        Queue::fake();
        $this->setupDefaults();
        Settings::update('stock-dms-navigator-sync-only-available-for-sale', true);

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);
        Vehicle::factory()->create([
            'uuid' => 'STK-002',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Available for Sale' => true, 'Export' => true]),
                        $this->vehiclePayload([
                            'STOCK' => 'STK-002',
                            'Available for Sale' => false,
                            'Export' => false,
                        ]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertEquals(1, Vehicle::query()->count());
        $this->assertTrue(Vehicle::query()->where('uuid', 'STK-001')->exists());
    }

    public function testRemovesOldVehiclesNotInFeed()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'stock_provider' => 'dms-navigator',
            'uuid' => 'OLD-STK',
            'is_published' => true,
        ]);
        Vehicle::factory()->create([
            'stock_provider' => 'dms-navigator',
            'uuid' => 'STK-001',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertFalse(Vehicle::query()->where('uuid', 'OLD-STK')->exists());
        $this->assertTrue(Vehicle::query()->where('uuid', 'STK-001')->exists());
    }

    public function testFetchReturnsEmptyOnApiFailure()
    {
        $this->setupDefaults();

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response('Error', 500),
        ]);

        $dms = new DMSNavigator();
        $result = $dms->fetchVehicles('https://services.dmservices.co.uk/test');

        $this->assertTrue($result->isEmpty());
    }

    public function testUpdatesExistingVehicle()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'stock_provider' => 'dms-navigator',
            'uuid' => 'STK-001',
            'price' => 18000,
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(['Web price' => 22000]),
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertEquals(1, Vehicle::query()->count());
        $this->assertEquals(22000, (int) Vehicle::query()->first()->price);
    }

    public function testDeduplicatesByStockId()
    {
        Queue::fake();
        $this->setupDefaults();

        Vehicle::factory()->create([
            'uuid' => 'STK-001',
            'stock_provider' => 'dms-navigator',
            'is_published' => true,
        ]);

        Http::fake([
            'https://services.dmservices.co.uk/*' => Http::response([
                'x:reports' => [
                    'report' => [
                        $this->vehiclePayload(),
                        $this->vehiclePayload(), // duplicate STOCK id
                    ],
                ],
            ]),
        ]);

        Dealership::factory()->create(['data' => ['dms-navigator-dealer-id' => 'LOC-1']]);
        (new DMSNavigator())->runScheduledImport();

        $this->assertEquals(1, Vehicle::query()->count());
    }
}
