<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Facades\TaxonomyMapper;
use App\Services\TaxonomyMappingService;
use App\VehicleSpec\Jobs\VehicleCapIdLookupViaHPI;
use Database\Seeders\Tenant\CapIdLocalCacheSettingSeeder;
use Database\Seeders\Tenant\HPICapIdLookupSettingSeeder;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Schema;
use Mtc\MercuryDataModels\CapIdCache;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Tests\TenantTestCase;

class VehicleCapIdLookupViaHPITest extends TenantTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        $this->seed(HPICapIdLookupSettingSeeder::class);
        $this->seed(CapIdLocalCacheSettingSeeder::class);

        Settings::update('cap-id-lookup-hpi-enabled', true);
        Settings::update('cap-id-lookup-local-cache-enabled', true);

        Config::set('tenancy.database.central_connection', config('database.default'));
        $this->createTaxonomyMapTables();

        // UsesTenancy mocks TaxonomyMapper to return null; these tests exercise real mapping
        TaxonomyMapper::swap($this->app->make(TaxonomyMappingService::class));
    }

    private function createTaxonomyMapTables(): void
    {
        if (!Schema::hasTable('taxonomy_map')) {
            Schema::create('taxonomy_map', function (Blueprint $table) {
                $table->id();
                $table->nullableMorphs('taxonomy');
                $table->string('term')->index();
                $table->string('provider')->index();
                $table->json('details')->nullable();
                $table->foreignId('parent_id')->nullable()->index();
                $table->timestamps();
            });
        }

        if (!Schema::hasTable('taxonomy_mapables')) {
            Schema::create('taxonomy_mapables', function (Blueprint $table) {
                $table->id();
                $table->string('tenant');
                $table->foreignId('taxonomy_map_id')->index();
                $table->morphs('mappable');
            });
        }
    }

    public function testModelMappingFallsBackToSmmtDescriptionWhenDvlaDoesNotMatch(): void
    {
        Http::fake(['wss.hpi.co.uk/*' => Http::response($this->hpiResponse())]);

        $make = VehicleMake::factory()->create(['name' => 'CUPRA']);
        $model = VehicleModel::factory()->create(['name' => 'TERRAMAR', 'make_id' => $make->id]);

        $vehicle = Vehicle::factory()->create([
            'cap_id' => null,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '1.5 eTSI V2 5dr DSG',
        ]);

        (new VehicleCapIdLookupViaHPI($vehicle))->handle();

        $this->assertEquals(106927, $vehicle->fresh()->cap_id);
        $this->assertEquals('CUTR15V2 5HPTA', $vehicle->fresh()->cap_code);

        $cacheEntry = CapIdCache::query()->where('derivative', '1.5 eTSI V2 5dr DSG')->first();
        $this->assertNotNull($cacheEntry);
        $this->assertEquals($make->id, $cacheEntry->cap_matched_make_id);
        // DVLA "TERRAMAR V2 ETSI S-A" has no exact taxonomy match; SMMT "TERRAMAR (SE336)" resolves
        $this->assertEquals($model->id, $cacheEntry->cap_matched_model_id);
    }

    public function testModelMappingPrefersExactDvlaMatch(): void
    {
        Http::fake(['wss.hpi.co.uk/*' => Http::response($this->hpiResponse())]);

        $make = VehicleMake::factory()->create(['name' => 'CUPRA']);
        $dvlaModel = VehicleModel::factory()->create([
            'name' => 'TERRAMAR V2 ETSI S-A',
            'make_id' => $make->id,
        ]);
        VehicleModel::factory()->create(['name' => 'TERRAMAR', 'make_id' => $make->id]);

        $vehicle = Vehicle::factory()->create([
            'cap_id' => null,
            'make_id' => $make->id,
            'model_id' => $dvlaModel->id,
            'derivative' => '1.5 eTSI V2 5dr DSG',
        ]);

        (new VehicleCapIdLookupViaHPI($vehicle))->handle();

        $cacheEntry = CapIdCache::query()->where('derivative', '1.5 eTSI V2 5dr DSG')->first();
        $this->assertNotNull($cacheEntry);
        $this->assertEquals($dvlaModel->id, $cacheEntry->cap_matched_model_id);
    }

    public function testCapIdStoredWhenModelCannotBeMappedAtAll(): void
    {
        Http::fake(['wss.hpi.co.uk/*' => Http::response($this->hpiResponse())]);

        $make = VehicleMake::factory()->create(['name' => 'CUPRA']);

        $vehicle = Vehicle::factory()->create([
            'cap_id' => null,
            'make_id' => $make->id,
            'model_id' => null,
            'derivative' => '1.5 eTSI V2 5dr DSG',
        ]);

        (new VehicleCapIdLookupViaHPI($vehicle))->handle();

        $this->assertEquals(106927, $vehicle->fresh()->cap_id);

        $cacheEntry = CapIdCache::query()->where('derivative', '1.5 eTSI V2 5dr DSG')->first();
        $this->assertNotNull($cacheEntry);
        $this->assertEquals($make->id, $cacheEntry->cap_matched_make_id);
        $this->assertNull($cacheEntry->cap_matched_model_id);
    }

    private function hpiResponse(): string
    {
        return <<<'XML'
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:EnquiryResponse xmlns:ns1="http://webservices.hpi.co.uk/SupplementaryEnquiryV1"><ns1:RequestResults><ns1:Asset><ns1:AssetIdentification><ns1:Vrm>AB12CDE</ns1:Vrm><ns1:Vin>TESTVIN0000000001</ns1:Vin><ns1:Reference></ns1:Reference></ns1:AssetIdentification><ns1:PrimaryAssetData xsi:type="ns1:IdCheckAssetType"><ns1:DVLA><ns1:Make><ns1:Code>JT</ns1:Code><ns1:Description>CUPRA</ns1:Description></ns1:Make><ns1:Model><ns1:Code>081</ns1:Code><ns1:Description>TERRAMAR V2 ETSI S-A</ns1:Description></ns1:Model><ns1:Body><ns1:Code>14</ns1:Code><ns1:Description>Hatchback</ns1:Description><ns1:Doors>5</ns1:Doors></ns1:Body><ns1:Engine><ns1:Size>1498</ns1:Size><ns1:Fuel><ns1:Code>8</ns1:Code><ns1:Description>Hybrid Electric</ns1:Description></ns1:Fuel></ns1:Engine></ns1:DVLA><ns1:SMMT><ns1:Make><ns1:Code>K0</ns1:Code><ns1:Description>CUPRA</ns1:Description></ns1:Make><ns1:Model><ns1:Code>AF</ns1:Code><ns1:Description>TERRAMAR (SE336)</ns1:Description></ns1:Model><ns1:Body><ns1:Code>D</ns1:Code><ns1:Description>Hatchback</ns1:Description><ns1:Doors>5</ns1:Doors></ns1:Body><ns1:Transmission><ns1:Code>9</ns1:Code><ns1:Description>7 Speed S-Auto Petrol</ns1:Description></ns1:Transmission></ns1:SMMT><ns1:CrossReference>VIN/VRM Combination is Confirmed</ns1:CrossReference></ns1:PrimaryAssetData><ns1:SupplementaryAssetData><ns1:CAP><ns1:MatchCode>08</ns1:MatchCode><ns1:CAPCode>CUTR15V2 5HPTA</ns1:CAPCode><ns1:CAPId>106927</ns1:CAPId><ns1:VehicleType>C</ns1:VehicleType></ns1:CAP></ns1:SupplementaryAssetData></ns1:Asset></ns1:RequestResults></ns1:EnquiryResponse></soapenv:Body></soapenv:Envelope>
XML;
    }
}
