<?php

namespace Tests\Unit;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\VehicleLookup\Config\AutoTraderConfig;
use Mtc\VehicleLookup\Contracts\SupportsOptionalExtras;
use Mtc\VehicleLookup\Contracts\VehicleOptionalEquipmentItem;
use Mtc\VehicleLookup\Drivers\AutoTrader;
use Tests\TestCase;

class AutoTraderLookupTest extends TestCase
{
    private AutoTrader $driver;

    protected function setUp(): void
    {
        parent::setUp();

        Cache::shouldReceive('remember')->andReturn('fake-access-token');

        config([
            'lookup.drivers.auto-trader.api_key' => 'test-key',
            'lookup.drivers.auto-trader.api_secret' => 'test-secret',
            'lookup.drivers.auto-trader.merchant_id' => '12345',
            'lookup.drivers.auto-trader.live' => false,
        ]);

        $this->driver = new AutoTrader(new AutoTraderConfig());
    }

    public function test_find_derivatives_returns_empty_array_when_generations_missing(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/*' => Http::response([]),
        ]);

        $make = new VehicleMake(['autotrader_id' => '1']);
        $model = new VehicleModel(['autotrader_id' => '2']);

        $result = $this->driver->findDerivatives($make, $model);

        $this->assertIsArray($result);
        $this->assertEmpty($result);
    }

    public function test_find_variants_returns_empty_array_when_derivatives_missing(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/*' => Http::response([]),
        ]);

        $make = new VehicleMake(['autotrader_id' => '1']);
        $model = new VehicleModel(['autotrader_id' => '2']);

        $result = $this->driver->findVariants($make, $model, 'gen-1');

        $this->assertIsArray($result);
        $this->assertEmpty($result);
    }

    public function test_driver_advertises_optional_extras_support(): void
    {
        $this->assertInstanceOf(SupportsOptionalExtras::class, $this->driver);
    }

    public function test_lookup_only_returns_standard_features_as_standard_equipment(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/*' => Http::response([
                'vehicle' => [
                    'make' => 'BMW',
                    'model' => '3 Series',
                    'vin' => 'WBAFAKE1234567890',
                ],
                'features' => [
                    ['name' => 'ABS', 'type' => 'Standard', 'category' => 'Safety'],
                    ['name' => 'Heated Seats', 'type' => 'Optional', 'category' => 'Comfort'],
                    ['name' => 'Cruise Control', 'type' => 'Standard', 'category' => 'Convenience'],
                ],
            ]),
        ]);

        $response = $this->driver->lookup('AB12CDE', 1000);

        $descriptions = $response->standard_equipment->pluck('description')->all();
        $this->assertSame(['ABS', 'Cruise Control'], $descriptions);
    }

    public function test_get_optional_extras_returns_only_optional_features(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([
                'vehicle' => [
                    'derivativeId' => 'DER-123',
                    'firstRegistrationDate' => '2022-03-01',
                ],
            ]),
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    [
                        'name' => '18" Alloy Wheels',
                        'type' => 'Optional',
                        'category' => 'Wheels',
                        'basicPrice' => 600,
                    ],
                    [
                        'name' => 'ABS',
                        'type' => 'Standard',
                        'category' => 'Safety',
                        'basicPrice' => 0,
                    ],
                    [
                        'name' => 'Panoramic Sunroof',
                        'type' => 'Optional',
                        'category' => 'Comfort',
                        'basicPrice' => 1200,
                    ],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $this->assertCount(2, $result);
        $this->assertContainsOnlyInstancesOf(VehicleOptionalEquipmentItem::class, $result);
        $this->assertSame('18" Alloy Wheels', $result[0]->description);
        $this->assertSame('Wheels', $result[0]->category_description);
        $this->assertSame(600.0, $result[0]->price);
        $this->assertSame('Panoramic Sunroof', $result[1]->description);
    }

    public function test_get_optional_extras_returns_empty_array_when_no_derivative_id(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $this->assertSame([], $result);
    }

    public function test_get_optional_extras_returns_empty_array_when_features_missing(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([
                'vehicle' => [
                    'derivativeId' => 'DER-123',
                    'firstRegistrationDate' => '2022-03-01',
                ],
            ]),
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $this->assertSame([], $result);
    }

    public function test_get_optional_extras_skips_entries_without_description(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([
                'vehicle' => [
                    'derivativeId' => 'DER-123',
                    'firstRegistrationDate' => '2022-03-01',
                ],
            ]),
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    ['name' => '', 'type' => 'Optional', 'category' => 'Misc'],
                    ['name' => 'Heated Seats', 'type' => 'Optional', 'category' => 'Comfort'],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $this->assertCount(1, $result);
        $this->assertSame('Heated Seats', $result[0]->description);
    }

    public function test_get_optional_extras_for_derivative_uses_provided_date(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    ['name' => 'Towbar', 'type' => 'Optional', 'category' => 'Exterior', 'basicPrice' => 450],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtrasForDerivative('DER-456', '2021-06-15');

        Http::assertSent(function ($request) {
            return str_contains($request->url(), 'derivativeId=DER-456')
                && str_contains($request->url(), 'effectiveDate=2021-06-15');
        });
        $this->assertCount(1, $result);
        $this->assertSame('Towbar', $result[0]->description);
    }

    public function test_get_optional_extras_for_derivative_defaults_effective_date_to_today(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response(['features' => []]),
        ]);

        $this->driver->getOptionalExtrasForDerivative('DER-456');

        $today = now()->format('Y-m-d');
        Http::assertSent(function ($request) use ($today) {
            return str_contains($request->url(), 'effectiveDate=' . $today);
        });
    }

    public function test_get_optional_extras_marks_factory_fitted_features_as_selected(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([
                'vehicle' => [
                    'derivativeId' => 'DER-123',
                    'firstRegistrationDate' => '2022-03-01',
                ],
                'features' => [
                    ['name' => 'Panoramic Sunroof', 'type' => 'Optional', 'factoryFitted' => true],
                    ['name' => 'ABS', 'type' => 'Standard', 'factoryFitted' => true],
                    ['name' => '18" Alloy Wheels', 'type' => 'Optional', 'factoryFitted' => false],
                ],
            ]),
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    ['name' => '18" Alloy Wheels', 'type' => 'Optional', 'category' => 'Wheels', 'basicPrice' => 600],
                    ['name' => 'Panoramic Sunroof', 'type' => 'Optional', 'category' => 'Comfort', 'basicPrice' => 1200],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $selected = collect($result)->mapWithKeys(
            fn (VehicleOptionalEquipmentItem $item) => [$item->description => $item->is_selected]
        );

        $this->assertTrue($selected['Panoramic Sunroof']);
        $this->assertFalse($selected['18" Alloy Wheels']);
    }

    public function test_get_optional_extras_for_derivative_has_no_selections_without_fitted_list(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    ['name' => 'Towbar', 'type' => 'Optional', 'category' => 'Exterior', 'basicPrice' => 450],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtrasForDerivative('DER-456');

        $this->assertFalse($result[0]->is_selected);
    }

    public function test_get_optional_extras_deduplicates_by_description(): void
    {
        Http::fake([
            'https://api-sandbox.autotrader.co.uk/vehicles*' => Http::response([
                'vehicle' => [
                    'derivativeId' => 'DER-123',
                    'firstRegistrationDate' => '2022-03-01',
                ],
            ]),
            'https://api-sandbox.autotrader.co.uk/taxonomy/features*' => Http::response([
                'features' => [
                    ['name' => 'Metallic Paint', 'type' => 'Optional', 'category' => 'Exterior'],
                    ['name' => 'Metallic Paint', 'type' => 'Optional', 'category' => 'Exterior'],
                ],
            ]),
        ]);

        $result = $this->driver->getOptionalExtras('AB12CDE');

        $this->assertCount(1, $result);
    }
}
