<?php

namespace Tests\Tenant;

use App\Events\NewVehicleImported;
use App\Facades\Settings;
use App\VehicleRepository;
use App\VehicleSpec\Config\AutoTraderConfig;
use App\VehicleSpec\Config\CapConfig;
use App\VehicleSpec\Contracts\VehicleSpecData;
use App\VehicleSpec\Contracts\VehicleStandardEquipmentItem;
use App\VehicleSpec\Contracts\VehicleTechnicalDataItem;
use App\VehicleSpec\Jobs\FetchVehicleSpecData;
use App\VehicleSpec\Jobs\VehicleCapIdLookup;
use App\VehicleSpec\Services\Cap;
use App\VehicleSpec\VehicleSpecServiceHelper;
use App\VehicleType;
use Database\Seeders\Tenant\AutoTraderStockSettingSeeder;
use Database\Seeders\Tenant\VehicleSpecSeeder;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Str;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleSpecType;
use Mtc\MercuryDataModels\VehicleStandardEquipment;
use Mtc\MercuryDataModels\VehicleTechnicalData;
use Mtc\VehicleLookup\VehicleLookupResponse;
use Tests\TenantTestCase;

class VehicleSpecTest extends TenantTestCase
{
    public function testSpecProviderCredentials()
    {
        $this->seed(VehicleSpecSeeder::class);
        Settings::update('vehicle-spec-providers-cap-enabled', true);

        $this->assertTrue(new CapConfig()->enabled());
    }

    public function testCapConfigured()
    {
        $this->seed(VehicleSpecSeeder::class);
        Settings::update('vehicle-spec-providers-cap-enabled', true);

        $spec_service_helper = VehicleSpecServiceHelper::initializeForSite();
        $this->assertInstanceOf(Cap::class, $spec_service_helper);
    }

    public function testCapNotConfigured()
    {
        $this->seed(VehicleSpecSeeder::class);

        $spec_service_helper = VehicleSpecServiceHelper::initializeForSite();
        $this->assertNull($spec_service_helper);
    }

    public function testCapSpecGet()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetStandardEquipment' => $this->getCapSpecResponse(),
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetTechnicalData' => $this->getCapTechDataResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // suzuki swift
        // CAP ID 79652
        // VRM: NG18HHS

        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->type = VehicleType::CAR->value;

        $spec = (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        $cylinder_count = 0;

        if (is_iterable($spec->technical_data)) {
            foreach ($spec->technical_data as $tech_item) {
                if (strtolower((string) $tech_item->description) === 'cylinders') {
                    $cylinder_count = $tech_item->value;
                }
            }
        }

        $has_cruise_control = false;

        if (is_iterable($spec->standard_equipment)) {
            foreach ($spec->standard_equipment as $item) {
                if (strtolower((string) $item->description) === 'cruise control') {
                    $has_cruise_control = true;
                }
            }
        }

        $this->assertInstanceOf(VehicleSpecData::class, $spec);
        $this->assertEquals(4, $cylinder_count);
        $this->assertTrue($has_cruise_control);
    }

    public function testCapSpecGetVan()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetStandardEquipment' => $this->getCapSpecResponse(),
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetTechnicalData' => $this->getCapTechDataResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // Mitsubishi L200
        // cap id: 45491

        $vehicle = new Vehicle();
        $vehicle->registration_number = '';
        $vehicle->cap_id = '45491';
        $vehicle->type = VehicleType::LCV->value;

        $result = (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        $this->assertInstanceOf(VehicleSpecData::class, $result);
    }

    public function testDatabaseTables()
    {
        $this->seed(VehicleSpecSeeder::class);

        $test_vehicle_spec = VehicleStandardEquipment::first();

        $this->assertEmpty($test_vehicle_spec);
    }

    public function testWriteToDatabase()
    {
        $this->seed(VehicleSpecSeeder::class);

        // create new model row
        $vehicle_spec = VehicleStandardEquipment::query()->create([
            'vehicle_id' => 1
        ]);

        $this->assertModelExists($vehicle_spec);
    }

    public function testInstanceNotInDatabase()
    {
        $this->seed(VehicleSpecSeeder::class);

        // instantiate object without saving to db
        $vehicle_spec = new VehicleStandardEquipment();
        $vehicle_spec->vehicle_id = 123;

        $this->assertModelMissing($vehicle_spec);
    }

    public function testPersistVehicleSpec()
    {
        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->vehicle_type = VehicleType::CAR;
        $vehicle->id = 1;

        $item1 = new VehicleStandardEquipmentItem(
            'abc123',
            'example item',
            'example category'
        );

        $item2 = new VehicleStandardEquipmentItem(
            'def789',
            'another example item',
            'example category'
        );

        $collection = collect([
            $item1,
            $item2
        ]);

        foreach ($collection as $item) {
            VehicleStandardEquipment::query()->create([
                'vehicle_id' => $vehicle->id,
                'type' => VehicleSpecType::STANDARD_EQUIPMENT,
                'description' => $item->description,
                'category' => $item->category_description
            ]);
        }

        // check that the number of items retrieved from CAP matches the number inserted into the db
        $this->assertEquals($collection->count(), VehicleStandardEquipment::count());
    }

    public function testPersistTechData()
    {
        // get tech data from CAP
        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->vehicle_type = VehicleType::CAR;
        $vehicle->id = 1;

        $item1 = new VehicleTechnicalDataItem(
            'code',
            'category',
            'description',
            'string value'
        );

        $item2 = new VehicleTechnicalDataItem(
            'code2',
            'category2',
            'description2',
            'string value2'
        );

        $collection = collect([
            $item1,
            $item2
        ]);

        // persist tech data to db
        foreach ($collection as $item) {
            VehicleTechnicalData::query()->create([
                'vehicle_id' => $vehicle->id,
                'code' => $item->code,
                'description' => $item->description,
                'value' => $item->value,
                'category' => $item->category
            ]);
        }

        // check that the number of items retrieved from CAP matches the number inserted into the db
        $this->assertEquals($collection->count(), VehicleTechnicalData::count());
    }

    public function testAutotraderConfigured()
    {
        $this->seed(VehicleSpecSeeder::class);
        Settings::update('vehicle-spec-providers-autotrader-enabled', true);

        $this->assertTrue(new AutoTraderConfig()->enabled());
    }

    public function testAutotraderNotConfigured()
    {
        $this->seed(VehicleSpecSeeder::class);

        $this->assertFalse(new AutoTraderConfig()->enabled());
    }

    public function testAutotraderSpecGet()
    {
        $this->seed(AutoTraderStockSettingSeeder::class);
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-autotrader-enabled', true);

        $dealership = Dealership::factory()->create();
        $dealership->data = ['auto-trader-location-id' => 12345];
        $dealership->save();
        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->vehicle_type = VehicleType::CAR;
        $vehicle->dealership_id = $dealership->id;

        $vehicle_data_url = 'https://api-sandbox.autotrader.co.uk/vehicles?'
            . http_build_query([
                'registration' => $vehicle->registration_number,
                'advertiserId' => 12345
            ]);

        $get_standard_equipment_url = 'https://api-sandbox.autotrader.co.uk/taxonomy/features';
        $get_standard_equipment_url .= '?' . http_build_query([
                'derivativeId' => '4660db704a004372bca771519a2a1c27',
                'effectiveDate' => '2018-07-31',
                'advertiserId' => 12345
            ]);

        $get_tech_data_url = 'https://api-sandbox.autotrader.co.uk/taxonomy/derivatives/'
            . '4660db704a004372bca771519a2a1c27?' . http_build_query([
                'advertiserId' => 12345
            ]);

        Http::fake([
            $get_standard_equipment_url => $this->getAutotraderStandardEquipmentResponse(),
            $get_tech_data_url => $this->getAutotraderTechDataResponse(),
            $vehicle_data_url => $this->getAutotraderVehicleResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // suzuki swift
        // CAP ID 79652
        // VRM: NG18HHS

        $spec = (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        $cylinder_count = 0;

        foreach ($spec->technical_data as $tech_item) {
            if (strtolower((string) $tech_item->description) === 'cylinders') {
                $cylinder_count = $tech_item->value;
            }
        }

        $has_bluetooth = false;

        foreach ($spec->standard_equipment as $item) {
            if (strtolower((string) $item->description) === 'bluetooth integrated into audio unit') {
                $has_bluetooth = true;
            }
        }

        $this->assertInstanceOf(VehicleSpecData::class, $spec);
        $this->assertEquals(4, $cylinder_count);
        $this->assertTrue($has_bluetooth);
    }

    public function testCapIdLookupVin()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/DVLA/CAPDVLA.asmx/DVLALookupVIN' => $this->getCapVinResponse(),
            'https://soap.cap.co.uk/DVLA/CAPDVLA.asmx/DVLALookupVRM' => $this->getCapVrmResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        $vehicle = Vehicle::factory()->create([
            'vin' => 'W1NFB2DE3PA920269',
            'cap_id' => null,
        ]);

        Queue::fake([FetchVehicleSpecData::class]);
        new VehicleCapIdLookup($vehicle)->handle();

        $vehicle->refresh();
        $this->assertEquals('88293', $vehicle->cap_id);
        Queue::assertPushed(FetchVehicleSpecData::class);
    }

    public function testCapIdLookupVrm()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/DVLA/CAPDVLA.asmx/DVLALookupVIN' => $this->getCapVinResponse(),
            'https://soap.cap.co.uk/DVLA/CAPDVLA.asmx/DVLALookupVRM' => $this->getCapVrmResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        $vehicle = Vehicle::factory()->create([
            'vin' => null,
            'registration_number' => 'KS23 OCE',
            'cap_id' => null,
        ]);
        Queue::fake([FetchVehicleSpecData::class]);
        new VehicleCapIdLookup($vehicle)->handle();

        $vehicle->refresh();
        $this->assertEquals('88293', $vehicle->cap_id);
        Queue::assertPushed(FetchVehicleSpecData::class);
    }

    public function testJobsTriggeredForNewVehicleWithoutCapId()
    {
        $this->seed(VehicleSpecSeeder::class);
        Queue::fake();
        Settings::update('vehicle-spec-providers-cap-enabled', true);
        $vehicle = Vehicle::factory()->create(['cap_id' => null]);
        Event::dispatch(new NewVehicleImported($vehicle, []));
        Queue::assertPushed(VehicleCapIdLookup::class);
        Queue::assertNotPushed(FetchVehicleSpecData::class);
    }

    public function testJobsTriggeredForNewVehicleWithCapId()
    {
        $this->seed(VehicleSpecSeeder::class);
        Queue::fake();
        Settings::update('vehicle-spec-providers-cap-enabled', true);
        $vehicle = Vehicle::factory()->create(['cap_id' => 'foo123']);
        Event::dispatch(new NewVehicleImported($vehicle, []));
        Queue::assertNotPushed(VehicleCapIdLookup::class);
        Queue::assertPushed(FetchVehicleSpecData::class);
    }

    public function testSanitiseAdditionalValueRejectsSentinelStringsForNumericColumns()
    {
        $job = new FetchVehicleSpecData(new Vehicle());
        $sanitise = new \ReflectionMethod($job, 'sanitiseAdditionalValue');

        // Sentinel strings from upstream spec providers must not reach numeric columns.
        $this->assertNull($sanitise->invoke($job, 'battery_quick_charge_time', 'Unspecified'));
        $this->assertNull($sanitise->invoke($job, 'battery_charge_time', 'Not Applicable'));
        $this->assertNull($sanitise->invoke($job, 'battery_capacity_kwh', 'unknown'));
        $this->assertNull($sanitise->invoke($job, 'mpg', 'N/A'));

        // Numeric strings pass through unchanged.
        $this->assertSame('60', $sanitise->invoke($job, 'battery_quick_charge_time', '60'));
        $this->assertSame('45.5', $sanitise->invoke($job, 'mpg', '45.5'));

        // battery_quick_charge_level keeps its regex extraction of the upper bound.
        $this->assertSame('80', $sanitise->invoke($job, 'battery_quick_charge_level', '20-80'));

        // plug_type / rapid_charge_plug_type are string columns; the connector name is preserved.
        $this->assertSame('Type 2 (Mennekes)', $sanitise->invoke($job, 'plug_type', 'Type 2 (Mennekes)'));
        $this->assertSame('CCS', $sanitise->invoke($job, 'rapid_charge_plug_type', 'CCS'));
    }

    public function testVehicleTypeLogicString()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetStandardEquipment' => $this->getCapSpecResponse(),
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetTechnicalData' => $this->getCapTechDataResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // suzuki swift
        // CAP ID 79652
        // VRM: NG18HHS

        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->type = 'car';

        (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        Http::assertSent(fn (Request $request) => Str::contains($request->body(), 'database=car'));
    }

    public function testVehicleTypeLogicEnum()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetStandardEquipment' => $this->getCapSpecResponse(),
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetTechnicalData' => $this->getCapTechDataResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // suzuki swift
        // CAP ID 79652
        // VRM: NG18HHS

        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->type = VehicleType::LCV;

        (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        Http::assertSent(fn (Request $request) => Str::contains($request->body(), 'database=lcv'));
    }

    public function testVehicleTypeLogicInvalidObject()
    {
        $this->seed(VehicleSpecSeeder::class);

        Settings::update('vehicle-spec-providers-cap-enabled', true);
        Settings::update('vehicle-spec-providers-cap-subscriber_id', 12345);
        Settings::update('vehicle-spec-providers-cap-password', 'test_password');

        Http::fake([
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetStandardEquipment' => $this->getCapSpecResponse(),
            'https://soap.cap.co.uk/Nvd/CapNvd.asmx/GetTechnicalData' => $this->getCapTechDataResponse(),
            '*' => Http::response('Not found', 404),
        ]);

        // suzuki swift
        // CAP ID 79652
        // VRM: NG18HHS

        $vehicle = new Vehicle();
        $vehicle->registration_number = 'NG18HHS';
        $vehicle->cap_id = '79652';
        $vehicle->type = new Dealership();

        (VehicleSpecServiceHelper::initializeForSite())->getSpec($vehicle);

        Http::assertSent(fn (Request $request) => Str::contains($request->body(), 'database=&'));
    }

    public function testBikeType()
    {
        $response = new VehicleLookupResponse(
            registration_number: 'ABC123',
            vehicle_type: 'bike',
        );

        $result = App::make(VehicleRepository::class)->mapTechnicalData($response);

        $this->assertArrayHasKey('type', $result);
        $this->assertEquals('motorcycle', $result['type']->value);
    }

    public function testVehicleTypeMapsToLcvForVariousStrings()
    {
        $this->seed(VehicleSpecSeeder::class);

        $cases = [
            'Light Commercial Vehicle',
            'light commercial vehicle',
            'Panel Van',
            'van',
            'lcv',
        ];

        $repo = App::make(VehicleRepository::class);

        foreach ($cases as $input) {
            $response = new \Mtc\VehicleLookup\VehicleLookupResponse(
                registration_number: 'ABC123',
                vehicle_type: $input
            );

            $result = $repo->mapTechnicalData($response);

            $this->assertArrayHasKey('type', $result, "missing type for input: {$input}");
            $this->assertInstanceOf(\App\VehicleType::class, $result['type'], "type is not enum for input: {$input}");
            $this->assertEquals(\App\VehicleType::LCV->value, $result['type']->value, "unexpected mapping for input: {$input}");
        }

        $response = new \Mtc\VehicleLookup\VehicleLookupResponse(
            registration_number: 'XYZ123',
        );
        $result = $repo->mapTechnicalData($response);
        $this->assertSame(strtolower((string) $result['type']->value), 'car');
    }

    private function getCapSpecResponse()
    {
        return Http::response('<?xml version="1.0" encoding="utf-8"?>
            <CAPDataSetResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://soap.cap.co.uk/nvd">
              <Success>true</Success>
              <FailMessage />
              <Returned_DataSet>
                <xs:schema id="StandardEquipement" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                  <xs:element name="StandardEquipement" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                    <xs:complexType>
                      <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="SE">
                          <xs:complexType>
                            <xs:sequence>
                              <xs:element name="Se_OptionCode" type="xs:int" minOccurs="0" />
                              <xs:element name="Do_Description" type="xs:string" minOccurs="0" />
                              <xs:element name="Dc_Description" type="xs:string" minOccurs="0" />
                            </xs:sequence>
                          </xs:complexType>
                        </xs:element>
                      </xs:choice>
                    </xs:complexType>
                  </xs:element>
                </xs:schema>
                <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                  <StandardEquipement xmlns="">
                    <SE diffgr:id="SE2" msdata:rowOrder="1">
                      <Se_OptionCode>7088</Se_OptionCode>
                      <Do_Description>Average fuel consumption display</Do_Description>
                      <Dc_Description>Driver Convenience</Dc_Description>
                    </SE>
                    <SE diffgr:id="SE3" msdata:rowOrder="2">
                      <Se_OptionCode>107</Se_OptionCode>
                      <Do_Description>Cruise control</Do_Description>
                      <Dc_Description>Driver Convenience</Dc_Description>
                    </SE>
                    <SE diffgr:id="SE28" msdata:rowOrder="27">
                      <Se_OptionCode>5554</Se_OptionCode>
                      <Do_Description>Chrome door mirrors and handles</Do_Description>
                      <Dc_Description>Exterior Features</Dc_Description>
                    </SE>
                    <SE diffgr:id="SE30" msdata:rowOrder="29">
                      <Se_OptionCode>15946</Se_OptionCode>
                      <Do_Description>Colour keyed front bumper</Do_Description>
                      <Dc_Description>Exterior Features</Dc_Description>
                    </SE>
                    <SE diffgr:id="SE109" msdata:rowOrder="108">
                      <Se_OptionCode>2528</Se_OptionCode>
                      <Do_Description>18" alloy wheels</Do_Description>
                      <Dc_Description>Wheels</Dc_Description>
                    </SE>
                  </StandardEquipement>
                </diffgr:diffgram>
              </Returned_DataSet>
            </CAPDataSetResult>', 200);
    }

    private function getCapTechDataResponse()
    {
        return Http::response('<?xml version="1.0" encoding="utf-8"?>
            <CAPDataSetResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://soap.cap.co.uk/nvd">
              <Success>true</Success>
              <FailMessage />
              <Returned_DataSet>
                <xs:schema id="TechnicalData" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                  <xs:element name="TechnicalData" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                    <xs:complexType>
                      <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="Tech">
                          <xs:complexType>
                            <xs:sequence>
                              <xs:element name="Tech_TechCode" type="xs:int" minOccurs="0" />
                              <xs:element name="DT_LongDescription" type="xs:string" minOccurs="0" />
                              <xs:element name="Dc_Description" type="xs:string" minOccurs="0" />
                              <xs:element name="tech_value_string" type="xs:string" minOccurs="0" />
                            </xs:sequence>
                          </xs:complexType>
                        </xs:element>
                      </xs:choice>
                    </xs:complexType>
                  </xs:element>
                </xs:schema>
                <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                  <TechnicalData xmlns="">
                    <Tech diffgr:id="Tech1" msdata:rowOrder="0">
                      <Tech_TechCode>76</Tech_TechCode>
                      <DT_LongDescription>Automatic Transmission</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>Yes</tech_value_string>
                    </Tech>
                    <Tech diffgr:id="Tech2" msdata:rowOrder="1">
                      <Tech_TechCode>61</Tech_TechCode>
                      <DT_LongDescription>Catalytic Convertor</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>Yes</tech_value_string>
                    </Tech>
                    <Tech diffgr:id="Tech3" msdata:rowOrder="2">
                      <Tech_TechCode>20</Tech_TechCode>
                      <DT_LongDescription>CC</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>2268</tech_value_string>
                    </Tech>
                    <Tech diffgr:id="Tech4" msdata:rowOrder="3">
                      <Tech_TechCode>75</Tech_TechCode>
                      <DT_LongDescription>Cooling System</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>WATER</tech_value_string>
                    </Tech>
                    <Tech diffgr:id="Tech5" msdata:rowOrder="4">
                      <Tech_TechCode>57</Tech_TechCode>
                      <DT_LongDescription>Cylinder Layout</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>IN-LINE</tech_value_string>
                    </Tech>
                    <Tech diffgr:id="Tech6" msdata:rowOrder="5">
                      <Tech_TechCode>56</Tech_TechCode>
                      <DT_LongDescription>Cylinders</DT_LongDescription>
                      <Dc_Description>Engine and Drive Train</Dc_Description>
                      <tech_value_string>4</tech_value_string>
                    </Tech>
                  </TechnicalData>
                </diffgr:diffgram>
              </Returned_DataSet>
            </CAPDataSetResult>', 200);
    }

    private function getAutotraderVehicleResponse()
    {
        return Http::response([
            'vehicle' => [
                'derivativeId' => '4660db704a004372bca771519a2a1c27',
                'firstRegistrationDate' => '2018-07-31'
            ]
        ], 200);
    }

    private function getAutotraderStandardEquipmentResponse()
    {
        return Http::response([
            'features' => [
                '0' => [
                    'name' => 'Bluetooth Integrated into Audio Unit',
                    'genericName' => 'Bluetooth',
                    'type' => 'Standard',
                    'category' => 'Audio and Communications',
                    'basicPrice' => '0',
                    'vatPrice' => '0'
                ]
            ],
        ], 200);
    }

    private function getAutotraderTechDataResponse()
    {
        return Http::response([
            'cylinders' => 4,
            'seats' => 5,
            'doors' => 5
        ], 200);
    }

    private function getCapVinResponse()
    {

        return Http::response('<?xml version="1.0" encoding="utf-8"?>
            <RESPONSE>
              <SUCCESS>true</SUCCESS>
              <ERRORMESSAGE>
              </ERRORMESSAGE>
              <TIMESTAMP>27/07/2023 11:52:13</TIMESTAMP>
              <AUDITID>154821696</AUDITID>
              <LOOKUP_VRM />
              <LOOKUP_VIN>W1NFB2DE3PA920269</LOOKUP_VIN>
              <MONTHLYLOOKUPLIMITEXCEEDED>False</MONTHLYLOOKUPLIMITEXCEEDED>
              <AUTOCORRECTED>False</AUTOCORRECTED>
              <AUTOCORRECTEDREASON>
              </AUTOCORRECTEDREASON>
              <MATCHLEVEL>
                <DVLA>1</DVLA>
                <DVLAKEEPER>0</DVLAKEEPER>
                <DVLABASIC>1</DVLABASIC>
                <SMMT>0</SMMT>
                <CAP>1</CAP>
                <ALTERNATIVEVRMS>0</ALTERNATIVEVRMS>
                <ALTERNATIVEDERIVATIVES>0</ALTERNATIVEDERIVATIVES>
              </MATCHLEVEL>
              <DATA>
                <DVLA>
                  <VRM>KS23OCE</VRM>
                  <VIN>W1NFB2DE3PA920269</VIN>
                  <MANUFACTURER>MERCEDES-BENZ</MANUFACTURER>
                  <MODEL>GLE 400 AMG LINE PREM + D</MODEL>
                  <FUELTYPE>Diesel</FUELTYPE>
                  <BODYTYPE>Estate</BODYTYPE>
                  <DOORS>5</DOORS>
                  <SEATING>7</SEATING>
                  <WHEELPLAN>2 Axle Rigid Body</WHEELPLAN>
                  <REGISTRATIONDATE>20230429</REGISTRATIONDATE>
                  <MANUFACTUREDDATE>20230429</MANUFACTUREDDATE>
                  <FIRSTREG_DATE>20230429</FIRSTREG_DATE>
                  <FIRSTREG_USEDBEFORE>0</FIRSTREG_USEDBEFORE>
                  <CO2>220</CO2>
                  <ENGINECAPACITY>2925</ENGINECAPACITY>
                  <ENGINENUMBER>65692980263658</ENGINENUMBER>
                  <ISSCRAPPED>No</ISSCRAPPED>
                  <SCRAPPEDDATE>
                  </SCRAPPEDDATE>
                  <ISEXPORTED>No</ISEXPORTED>
                  <EXPORTEDDATE>
                  </EXPORTEDDATE>
                  <ISIMPORTED>No</ISIMPORTED>
                  <IMPORTEDDATE>
                  </IMPORTEDDATE>
                  <COLOUR>RED</COLOUR>
                  <MASSINSERVICE>2280</MASSINSERVICE>
                  <MAXMASS>3220</MAXMASS>
                  <MAXNETPOWER>243</MAXNETPOWER>
                  <MAXTOW_BRAKED>2700</MAXTOW_BRAKED>
                  <MAXTOW_UNBRAKED>750</MAXTOW_UNBRAKED>
                  <SOUNDLEVEL_STATIONARY>77</SOUNDLEVEL_STATIONARY>
                  <SOUNDLEVEL_ENGINE>3150</SOUNDLEVEL_ENGINE>
                  <SOUNDLEVEL_DRIVEBY>71</SOUNDLEVEL_DRIVEBY>
                  <PREVIOUSAQUISITION>
                  </PREVIOUSAQUISITION>
                  <PREVIOUSDISPOSAL>
                  </PREVIOUSDISPOSAL>
                  <PREVIOUSKEEPERS>
                  </PREVIOUSKEEPERS>
                  <CHERISHEDTRANSFERMARKER>No</CHERISHEDTRANSFERMARKER>
                  <TRANSFERDATE>
                  </TRANSFERDATE>
                </DVLA>
                <CAP>
                  <VEHICLETYPE_ID>1</VEHICLETYPE_ID>
                  <VEHICLETYPE>Car</VEHICLETYPE>
                  <CAPID>88293</CAPID>
                  <CAPCODE>MEGE307AG5EDTA4 1   </CAPCODE>
                  <ENHANCEDCAPCODE>0108829320220622202206220735511960072101</ENHANCEDCAPCODE>
                  <ENHANCEDCAPCODE_IDENTIFIER>010882932022062220220622</ENHANCEDCAPCODE_IDENTIFIER>
                  <ENHANCEDCAPCODE_TECNICAL>0735511960072101</ENHANCEDCAPCODE_TECNICAL>
                  <MANUFACTURER_CODE>5509</MANUFACTURER_CODE>
                  <MANUFACTURER>MERCEDES-BENZ</MANUFACTURER>
                  <RANGE_CODE>1272</RANGE_CODE>
                  <RANGE>GLE</RANGE>
                  <MODEL_CODE>93388</MODEL_CODE>
                  <MODEL>GLE DIESEL ESTATE</MODEL>
                  <MODELDATEDESC_SHORT>(19 - 23)</MODELDATEDESC_SHORT>
                  <MODELDATEDESC_LONG>(2019 - 2023)</MODELDATEDESC_LONG>
                  <DERIVATIVE>GLE 400d 4Matic AMG Line Prem + 5dr 9G-Tron [7 St]</DERIVATIVE>
                  <DERIVATIVEDATEDESC_SHORT>(19 - 23)</DERIVATIVEDATEDESC_SHORT>
                  <DERIVATIVEDATEDESC_LONG>(2019 - 2023)</DERIVATIVEDATEDESC_LONG>
                  <INTRODUCED>20190501</INTRODUCED>
                  <DISCONTINUED>20230221</DISCONTINUED>
                  <RUNOUTDATE>20230831</RUNOUTDATE>
                  <DOORS>5</DOORS>
                  <DRIVETRAIN>Four Wheel Drive</DRIVETRAIN>
                  <FUELDELIVERY>Turbo</FUELDELIVERY>
                  <TRANSMISSION>Automatic</TRANSMISSION>
                  <FUELTYPE>Diesel</FUELTYPE>
                  <PLATE>2023 23</PLATE>
                  <PLATE_SEQNO>132</PLATE_SEQNO>
                  <PLATE_YEAR>2023</PLATE_YEAR>
                  <PLATE_MONTH>3</PLATE_MONTH>
                </CAP>
              </DATA>
            </RESPONSE>');
    }

    private function getCapVrmResponse()
    {
        return Http::response('<?xml version="1.0" encoding="utf-8"?>
            <RESPONSE>
              <SUCCESS>true</SUCCESS>
              <ERRORMESSAGE>
              </ERRORMESSAGE>
              <TIMESTAMP>27/07/2023 11:54:17</TIMESTAMP>
              <AUDITID>154822115</AUDITID>
              <LOOKUP_VRM>KS23 OCE</LOOKUP_VRM>
              <LOOKUP_VIN />
              <MONTHLYLOOKUPLIMITEXCEEDED>False</MONTHLYLOOKUPLIMITEXCEEDED>
              <AUTOCORRECTED>False</AUTOCORRECTED>
              <AUTOCORRECTEDREASON>
              </AUTOCORRECTEDREASON>
              <MATCHLEVEL>
                <DVLA>1</DVLA>
                <DVLAKEEPER>0</DVLAKEEPER>
                <DVLABASIC>1</DVLABASIC>
                <SMMT>0</SMMT>
                <CAP>1</CAP>
                <ALTERNATIVEVRMS>0</ALTERNATIVEVRMS>
                <ALTERNATIVEDERIVATIVES>0</ALTERNATIVEDERIVATIVES>
              </MATCHLEVEL>
              <DATA>
                <DVLA>
                  <VRM>KS23OCE</VRM>
                  <VIN>W1NFB2DE3PA920269</VIN>
                  <MANUFACTURER>MERCEDES-BENZ</MANUFACTURER>
                  <MODEL>GLE 400 AMG LINE PREM + D</MODEL>
                  <FUELTYPE>Diesel</FUELTYPE>
                  <BODYTYPE>Estate</BODYTYPE>
                  <DOORS>5</DOORS>
                  <SEATING>7</SEATING>
                  <WHEELPLAN>2 Axle Rigid Body</WHEELPLAN>
                  <REGISTRATIONDATE>20230429</REGISTRATIONDATE>
                  <MANUFACTUREDDATE>20230429</MANUFACTUREDDATE>
                  <FIRSTREG_DATE>20230429</FIRSTREG_DATE>
                  <FIRSTREG_USEDBEFORE>0</FIRSTREG_USEDBEFORE>
                  <CO2>220</CO2>
                  <ENGINECAPACITY>2925</ENGINECAPACITY>
                  <ENGINENUMBER>65692980263658</ENGINENUMBER>
                  <ISSCRAPPED>No</ISSCRAPPED>
                  <SCRAPPEDDATE>
                  </SCRAPPEDDATE>
                  <ISEXPORTED>No</ISEXPORTED>
                  <EXPORTEDDATE>
                  </EXPORTEDDATE>
                  <ISIMPORTED>No</ISIMPORTED>
                  <IMPORTEDDATE>
                  </IMPORTEDDATE>
                  <COLOUR>RED</COLOUR>
                  <MASSINSERVICE>2280</MASSINSERVICE>
                  <MAXMASS>3220</MAXMASS>
                  <MAXNETPOWER>243</MAXNETPOWER>
                  <MAXTOW_BRAKED>2700</MAXTOW_BRAKED>
                  <MAXTOW_UNBRAKED>750</MAXTOW_UNBRAKED>
                  <SOUNDLEVEL_STATIONARY>77</SOUNDLEVEL_STATIONARY>
                  <SOUNDLEVEL_ENGINE>3150</SOUNDLEVEL_ENGINE>
                  <SOUNDLEVEL_DRIVEBY>71</SOUNDLEVEL_DRIVEBY>
                  <PREVIOUSAQUISITION>
                  </PREVIOUSAQUISITION>
                  <PREVIOUSDISPOSAL>
                  </PREVIOUSDISPOSAL>
                  <PREVIOUSKEEPERS>
                  </PREVIOUSKEEPERS>
                  <CHERISHEDTRANSFERMARKER>No</CHERISHEDTRANSFERMARKER>
                  <TRANSFERDATE>
                  </TRANSFERDATE>
                </DVLA>
                <CAP>
                  <VEHICLETYPE_ID>1</VEHICLETYPE_ID>
                  <VEHICLETYPE>Car</VEHICLETYPE>
                  <CAPID>88293</CAPID>
                  <CAPCODE>MEGE307AG5EDTA4 1   </CAPCODE>
                  <ENHANCEDCAPCODE>0108829320220622202206220735511960072101</ENHANCEDCAPCODE>
                  <ENHANCEDCAPCODE_IDENTIFIER>010882932022062220220622</ENHANCEDCAPCODE_IDENTIFIER>
                  <ENHANCEDCAPCODE_TECNICAL>0735511960072101</ENHANCEDCAPCODE_TECNICAL>
                  <MANUFACTURER_CODE>5509</MANUFACTURER_CODE>
                  <MANUFACTURER>MERCEDES-BENZ</MANUFACTURER>
                  <RANGE_CODE>1272</RANGE_CODE>
                  <RANGE>GLE</RANGE>
                  <MODEL_CODE>93388</MODEL_CODE>
                  <MODEL>GLE DIESEL ESTATE</MODEL>
                  <MODELDATEDESC_SHORT>(19 - 23)</MODELDATEDESC_SHORT>
                  <MODELDATEDESC_LONG>(2019 - 2023)</MODELDATEDESC_LONG>
                  <DERIVATIVE>GLE 400d 4Matic AMG Line Prem + 5dr 9G-Tron [7 St]</DERIVATIVE>
                  <DERIVATIVEDATEDESC_SHORT>(19 - 23)</DERIVATIVEDATEDESC_SHORT>
                  <DERIVATIVEDATEDESC_LONG>(2019 - 2023)</DERIVATIVEDATEDESC_LONG>
                  <INTRODUCED>20190501</INTRODUCED>
                  <DISCONTINUED>20230221</DISCONTINUED>
                  <RUNOUTDATE>20230831</RUNOUTDATE>
                  <DOORS>5</DOORS>
                  <DRIVETRAIN>Four Wheel Drive</DRIVETRAIN>
                  <FUELDELIVERY>Turbo</FUELDELIVERY>
                  <TRANSMISSION>Automatic</TRANSMISSION>
                  <FUELTYPE>Diesel</FUELTYPE>
                  <PLATE>2023 23</PLATE>
                  <PLATE_SEQNO>132</PLATE_SEQNO>
                  <PLATE_YEAR>2023</PLATE_YEAR>
                  <PLATE_MONTH>3</PLATE_MONTH>
                </CAP>
              </DATA>
            </RESPONSE>');

    }
}
