<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use Carbon\Carbon;
use Database\Seeders\Tenant\AllowVehicleFinanceOverrideSetting;
use Database\Seeders\Tenant\CodeweaversVATSettingSeeder;
use Database\Seeders\Tenant\FinanceSettingSeeder;
use Database\Seeders\Tenant\PeterVardyFinanceSeeder;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Finance\Contracts\FinanceRequestData;
use Mtc\MercuryDataModels\Finance\FinanceServiceHelper;
use Mtc\MercuryDataModels\Finance\Jobs\FetchVehicleFinanceData;
use Mtc\MercuryDataModels\Finance\Services\CodeWeaversPeterVardy;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleAttribute;
use Mtc\MercuryDataModels\VehicleAttributeValue;
use Mtc\MercuryDataModels\VehicleFinance;
use Mtc\MercuryDataModels\VehicleMake;
use Tests\TenantTestCase;

class CodeWeaversServiceTest extends TenantTestCase
{
    public function testGoodRequestCalculation()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
        ));

        Http::assertSent(fn (Request $request) => $request->hasHeader('Content-Type', 'application/json')
            && $request->hasHeader('X-CW-ApiKey', 'Codeweavers-foo-baz-bar')
            && $request->url() === 'https://services.codeweavers.net/public/v3/jsonfinance/calculate'
            && $request['Credentials']['Username'] === 'lorem'
            && $request['Parameters']['Term'] === 60
            && $request['VehicleRequests'][0]['Vehicle']['CashPrice'] == 23456
            && $request['Credentials']['Password'] === 'ipsum'
            && $request['VehicleRequests'][0]['Vehicle']['Vin'] == ''
            && is_array($request['VehicleRequests'][0]['Products'])
            && empty($request['VehicleRequests'][0]['Products']));

        $this->assertEquals(2, $result->count());
        $finance = $result->filter(fn ($finance_example) => $finance_example->finance_type->value == 'PCP')->first();
        $this->assertEquals(123, $finance->monthly_price);
        $this->assertEquals(58, $finance->number_of_payments);
        $this->assertEquals(13, $finance->apr);
        $this->assertEquals(3000, $finance->total_deposit);
        $this->assertEquals(7000, $finance->cash_price);
        $this->assertEquals(0, $finance->dealer_deposit);
        $this->assertEquals(3000, $finance->customer_deposit);
        $this->assertEquals(600, $finance->deposit_tax_payable);
        $this->assertEquals(8393.68, $finance->payable_amount);
        $this->assertEquals(0, $finance->option_to_purchase_fee);
        $this->assertEquals(456, $finance->documentation_fee);

        $total_credit = $finance->cash_price - $finance->total_deposit;
        $this->assertEquals($total_credit, $finance->total_credit_amount);

        $hp = $result->filter(fn ($finance_example) => $finance_example->finance_type->value == 'HP')->first();
        $this->assertEquals(600, $hp->deposit_tax_payable);
    }

    public function testDepositTaxPayableIsNullWhenAbsent()
    {
        $response = $this->response();

        // Strip DepositTaxPayable from each Quote so we model the case where
        // Codeweavers returns no VAT figure (e.g. non-VAT-exclusive request).
        foreach ($response['VehicleResults'][0]['FinanceProductResults'] as &$product) {
            unset($product['Quote']['DepositTaxPayable']);
        }
        unset($product);

        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($response),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
        ));

        $finance = $result->filter(fn ($finance_example) => $finance_example->finance_type->value == 'PCP')->first();
        $this->assertNull($finance->deposit_tax_payable);
    }

    public function testPeterVardyCodeWeaversQuotes()
    {
        Http::fake(function (Request $request) {
            if (stripos((string) $request['Parameters']['SpecificProductType'], 'HP') !== false) {
                return Http::response($this->responseHp(), 200);
            } elseif (stripos((string) $request['Parameters']['SpecificProductType'], 'PCP') !== false) {
                return Http::response($this->responsePcp(), 200);
            } else {
                return Http::response([], 400);
            }
        });

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        $provider = FinanceServiceHelper::initializeForSite();

        $this->assertInstanceOf(CodeWeaversPeterVardy::class, $provider);

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            finance_option: 3,
        ));

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_B_') !== false);

        $this->assertCount(2, $result);
        $this->assertArrayHasKey('HP', $result);
        $this->assertArrayHasKey('PCP', $result);
        $this->assertEquals(456, $result['HP']->monthly_price);
        $this->assertEquals(789, $result['PCP']->monthly_price);
        $this->assertEquals('HP', $result['HP']->finance_type->name);
        $this->assertEquals('PCP', $result['PCP']->finance_type->name);
    }

    public function testPvCallPorsche()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'porsche test'
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            '',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => in_array(
            $request['Parameters']['SpecificProductType'],
            [
                'HP',
                'PCP',
            ]
        )
        && !array_key_exists('CustomerSelectedCreditTier', $request['Parameters']));
    }

    public function testPvCallBmw()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'BMW test'
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '3'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            '',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_B_') !== false
        && !array_key_exists('CustomerSelectedCreditTier', $request['Parameters']));
    }

    public function testPvCallMini()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'mini test'
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            '',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_A_') !== false
        && !array_key_exists('CustomerSelectedCreditTier', $request['Parameters']));
    }

    public function testPvCallJaguar()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'jaguar test'
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            '',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_A_') !== false
        && !array_key_exists('CustomerSelectedCreditTier', $request['Parameters']));
    }

    public function testPvCallLandRover()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'land rover test'
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            '',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_A_') !== false
        && !array_key_exists('CustomerSelectedCreditTier', $request['Parameters']));
    }

    public function testPvCallCarz()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');


        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_A_') !== false
        && stripos($request['Parameters']['CustomerSelectedCreditTier'] ?? '', 'BelowAverage') !== false);
    }

    public function testPvCallOmodaNew()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'carz test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle_make = VehicleMake::factory()->create([
            'name' => 'omoda'
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id,
            'make_id' => $vehicle_make->id,
            'is_new' => true,
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'OMODA_') !== false);
    }

    public function testPvCallOmodaUsed()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'carz test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle_make = VehicleMake::factory()->create([
            'name' => 'omoda'
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id,
            'make_id' => $vehicle_make->id,
            'is_new' => false,
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => stripos((string) $request['Parameters']['SpecificProductType'], 'CAT_A_') !== false);
    }

    public function testVehicleMake()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'carz test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle_make = VehicleMake::factory()->create([
            'name' => 'omoda'
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id,
            'make_id' => $vehicle_make->id,
            'is_new' => false,
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => array_key_exists('Manufacturer', $request['VehicleRequests'][0]['Vehicle'])
        && strtolower((string) $request['VehicleRequests'][0]['Vehicle']['Manufacturer']) == 'omoda');
    }

    public function testVehicleEmptyMake()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-per-dealer-keys'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'boolean',
            'value' => true,
            'config_key' => 'finance-risk-based-pricing-enabled'
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => '1',
            'config_key' => 'finance-risk-based-pricing-finance-options'
        ]);

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'carz test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id,
            'make_id' => null,
            'is_new' => false,
        ]);

        // add vehicle attribute for finance_option
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'finance option',
            'model' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'count' => 1
        ]);

        // set attribute value
        VehicleAttributeValue::factory()->create([
            'attribute_id' => $attribute->id,
            'owner_id' => $vehicle->id,
            'owner_type' => 'vehicle',
            'slug' => 'finance_option',
            'type' => 'string',
            'value' => '1'
        ]);

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        Http::assertSent(fn (Request $request) => array_key_exists('Manufacturer', $request['VehicleRequests'][0]['Vehicle']) == false);
    }

    /**
     * test solution for unpredictable codeweavers payment ordering
     *
     * @return void
     */
    public function testPaymentOrder()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
        ));

        Http::assertSent(fn (Request $request) => $request->hasHeader('Content-Type', 'application/json')
            && $request->hasHeader('X-CW-ApiKey', 'Codeweavers-foo-baz-bar')
            && $request->url() === 'https://services.codeweavers.net/public/v3/jsonfinance/calculate'
            && $request['Credentials']['Username'] === 'lorem'
            && $request['Parameters']['Term'] === 60
            && $request['VehicleRequests'][0]['Vehicle']['CashPrice'] == 23456
            && $request['Credentials']['Password'] === 'ipsum'
            && $request['VehicleRequests'][0]['Vehicle']['Vin'] == '');

        $this->assertEquals(2, $result->count());
        $finance = $result->filter(fn ($finance_example) => $finance_example->finance_type->value == 'PCP')->first();
        $this->assertEquals(132, $finance->first_payment);
        $this->assertEquals(123, $finance->monthly_price);
        $this->assertEquals(58, $finance->number_of_payments);
        $this->assertEquals(13, $finance->apr);
        $this->assertEquals(3000, $finance->total_deposit);
        $this->assertEquals(7000, $finance->cash_price);
        $this->assertEquals(0, $finance->dealer_deposit);
        $this->assertEquals(3000, $finance->customer_deposit);
        $this->assertEquals(8393.68, $finance->payable_amount);
        $this->assertEquals(0, $finance->option_to_purchase_fee);
        $this->assertEquals(456, $finance->documentation_fee);

        $total_credit = $finance->cash_price - $finance->total_deposit;
        $this->assertEquals($total_credit, $finance->total_credit_amount);
    }

    public function testTermsAndConditions()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->responseWithQuoteReference()),
            "https://services.codeweavers.net/api/finance/quote/*/termsandconditions" => Http::response($this->responseTermsAndConditions()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        $provider = FinanceServiceHelper::initializeForSite();

        $this->assertInstanceOf(CodeWeaversPeterVardy::class, $provider);

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            finance_option: 3,
        ));

        $this->assertCount(2, $result);
        $this->assertArrayHasKey('HP', $result);
        $this->assertArrayHasKey('PCP', $result);
        $this->assertEquals('lorem ipsum', $result['HP']->terms_and_conditions);
        $this->assertEquals('lorem ipsum', $result['PCP']->terms_and_conditions);
    }

    public function testTermsAndConditionsFailedCall()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->responseWithQuoteReference()),
            "https://services.codeweavers.net/api/finance/quote/*/termsandconditions" => Http::response([], 400),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        $provider = FinanceServiceHelper::initializeForSite();

        $this->assertInstanceOf(CodeWeaversPeterVardy::class, $provider);

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            finance_option: 3,
        ));

        $this->assertCount(2, $result);
        $this->assertArrayHasKey('HP', $result);
        $this->assertArrayHasKey('PCP', $result);
        $this->assertEquals('', $result['HP']->terms_and_conditions);
        $this->assertEquals('', $result['PCP']->terms_and_conditions);
    }

    public function testTermsAndConditionsEmpty()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->responseWithQuoteReference()),
            "https://services.codeweavers.net/api/finance/quote/*/termsandconditions" => Http::response($this->responseTermsAndConditionsEmpty()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        $provider = FinanceServiceHelper::initializeForSite();

        $this->assertInstanceOf(CodeWeaversPeterVardy::class, $provider);

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            finance_option: 3,
        ));

        $this->assertCount(2, $result);
        $this->assertArrayHasKey('HP', $result);
        $this->assertArrayHasKey('PCP', $result);
        $this->assertEquals('', $result['HP']->terms_and_conditions);
        $this->assertEquals('', $result['PCP']->terms_and_conditions);
    }

    public function testStoreDeletesOldQutoes()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(PeterVardyFinanceSeeder::class);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('vehicle-finance-type', 'peter-vardy');

        $dealer = Dealership::factory()->create([
            'id' => 99,
            'name' => 'porsche test',
            'data' => [
                'codeweavers' => 'carz test',
                'finance-risk-based-pricing' => true
            ],
        ]);

        $vehicle = Vehicle::factory()->create([
            'dealership_id' => $dealer->id
        ]);

        VehicleFinance::factory(10)->create([
            'vehicle_id' => $vehicle->id
        ]);

        VehicleFinance::factory(5)->create([
            'vehicle_id' => ($vehicle->id + 1)
        ]);

        $this->assertCount(15, VehicleFinance::all());
        $this->assertCount(10, VehicleFinance::query()->where('vehicle_id', '=', $vehicle->id)->get());
        $this->assertCount(5, VehicleFinance::query()->where('vehicle_id', '=', $vehicle->id + 1)->get());

        new FetchVehicleFinanceData(
            $vehicle,
            60,
            10000,
            10,
            'BELOW_AVERAGE',
            []
        )->handle();

        $this->assertCount(7, VehicleFinance::all());
        $this->assertCount(2, VehicleFinance::query()->where('vehicle_id', '=', $vehicle->id)->get());
        $this->assertCount(5, VehicleFinance::query()->where('vehicle_id', '=', $vehicle->id + 1)->get());
    }

    public function testProductKeys()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);
        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        $provider = FinanceServiceHelper::initializeForSite();
        $dealer = Dealership::factory()->create([
            'name' => 'test',
            'data' => [
                'codeweavers' => 'test',
                'codeweavers-product-keys' => 'key_one,key_two,key_three'
            ],
        ]);
        Vehicle::factory()->create([
            'uuid' => 'abc123',
            'dealership_id' => $dealer->id,
        ]);
        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'foo',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            extra: [
                'dealership_data' => $dealer->data,
            ],
        ));
        Http::assertSent(function (Request $request) {
            $product_keys = collect($request['VehicleRequests'][0]['Products'])->map(fn ($key) => $key['Key'])->toArray();
            return count($request['VehicleRequests'][0]['Products']) == 3
                && in_array('key_one', $product_keys)
                && in_array('key_two', $product_keys)
                && in_array('key_three', $product_keys);
        });
    }

    public function testAlternateFinanceKeyIgnoredWhenSettingDisabled()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);
        $this->seed(FinanceSettingSeeder::class);
        $this->seed(AllowVehicleFinanceOverrideSetting::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        // finance-allow-vehicle-override deliberately left at default (false)
        $provider = FinanceServiceHelper::initializeForSite();
        $dealer = Dealership::factory()->create([
            'name' => 'test',
            'data' => [
                'codeweavers' => 'test',
                'codeweavers-product-keys' => 'dealer_one,dealer_two',
            ],
        ]);
        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'foo',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            extra: [
                'dealership_data' => $dealer->data,
            ],
            alternate_finance_key: 'BLACKHORSE_NEW_HP,BLACKHORSE_NEW_PCP',
        ));
        Http::assertSent(function (Request $request) {
            $product_keys = collect($request['VehicleRequests'][0]['Products'])->map(fn ($key) => $key['Key'])->toArray();
            return count($request['VehicleRequests'][0]['Products']) == 2
                && in_array('dealer_one', $product_keys)
                && in_array('dealer_two', $product_keys)
                && !in_array('BLACKHORSE_NEW_HP', $product_keys)
                && !in_array('BLACKHORSE_NEW_PCP', $product_keys);
        });
    }

    public function testAlternateFinanceKeyUsedWhenSettingEnabled()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);
        $this->seed(FinanceSettingSeeder::class);
        $this->seed(AllowVehicleFinanceOverrideSetting::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-allow-vehicle-override', true);
        $provider = FinanceServiceHelper::initializeForSite();
        $dealer = Dealership::factory()->create([
            'name' => 'test',
            'data' => [
                'codeweavers' => 'test',
                'codeweavers-product-keys' => 'dealer_one,dealer_two',
            ],
        ]);
        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'foo',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            extra: [
                'dealership_data' => $dealer->data,
            ],
            alternate_finance_key: 'BLACKHORSE_NEW_HP,BLACKHORSE_NEW_PCP',
        ));
        Http::assertSent(function (Request $request) {
            $product_keys = collect($request['VehicleRequests'][0]['Products'])->map(fn ($key) => $key['Key'])->toArray();
            return count($request['VehicleRequests'][0]['Products']) == 2
                && in_array('BLACKHORSE_NEW_HP', $product_keys)
                && in_array('BLACKHORSE_NEW_PCP', $product_keys)
                && !in_array('dealer_one', $product_keys)
                && !in_array('dealer_two', $product_keys);
        });
    }

    public function testAlternateFinanceKeyTrimsWhitespaceAndIgnoresEmpty()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);
        $this->seed(FinanceSettingSeeder::class);
        $this->seed(AllowVehicleFinanceOverrideSetting::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-allow-vehicle-override', true);
        $provider = FinanceServiceHelper::initializeForSite();
        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'foo',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            alternate_finance_key: '  BLACKHORSE_NEW_HP , BLACKHORSE_NEW_PCP  ,,',
        ));
        Http::assertSent(function (Request $request) {
            $product_keys = collect($request['VehicleRequests'][0]['Products'])->map(fn ($key) => $key['Key'])->toArray();
            return count($request['VehicleRequests'][0]['Products']) == 2
                && in_array('BLACKHORSE_NEW_HP', $product_keys)
                && in_array('BLACKHORSE_NEW_PCP', $product_keys);
        });
    }

    public function testVATApplicabilityDisabled()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
        ));

        Http::assertSent(fn (Request $request) => !array_key_exists('CashValuesAreVatExclusive', $request['Parameters']));
    }

    public function testVATApplicabilityEnabledWithCar()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            is_vat_applicable: true,
        ));

        Http::assertSent(fn (Request $request) => !array_key_exists('CashValuesAreVatExclusive', $request['Parameters']));
    }

    public function testVATApplicabilityEnabledWithLCV()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);
        $provider = FinanceServiceHelper::initializeForSite();

        $result = $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            is_vat_applicable: false,
        ));

        Http::assertSent(fn (Request $request) => array_key_exists('CashValuesAreVatExclusive', $request['Parameters'])
            && $request['Parameters']['CashValuesAreVatExclusive'] == true);
    }

    public function testVATForMixedBatch()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);

        $batch = [
            new FinanceRequestData(
                uuid: 'xyz789',
                registration_number: 'SD12 FOO',
                cap_id: 1231122,
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: Carbon::create(2020, 1, 1),
                term: 60,
                mileage: 100000,
                annual_mileage: 13000,
                price: 23456,
                deposit: 3000,
                credit_rating: 'excellent',
                is_vat_applicable: true,
            ),
            new FinanceRequestData(
                uuid: 'abc123',
                registration_number: 'SD12 ABC',
                cap_id: 1231122,
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: Carbon::create(2020, 1, 1),
                term: 60,
                mileage: 100000,
                annual_mileage: 13000,
                price: 23456,
                deposit: 3000,
                credit_rating: 'excellent',
                is_vat_applicable: false,
            )
        ];

        $provider = FinanceServiceHelper::initializeForSite();
        $provider->batchRequest(collect($batch));

        // assert that batch of mixed vat applicable vehicles does NOT get CashValuesAreVatExclusive in the request
        Http::assertSent(fn (Request $request) => !array_key_exists('CashValuesAreVatExclusive', $request['Parameters']));
    }

    public function testVATForLCVBatch()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);

        $batch = [
            new FinanceRequestData(
                uuid: 'xyz789',
                registration_number: 'SD12 FOO',
                cap_id: 1231122,
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: Carbon::create(2020, 1, 1),
                term: 60,
                mileage: 100000,
                annual_mileage: 13000,
                price: 23456,
                deposit: 3000,
                credit_rating: 'excellent',
                is_vat_applicable: false,
            ),
            new FinanceRequestData(
                uuid: 'abc123',
                registration_number: 'SD12 ABC',
                cap_id: 1231122,
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: Carbon::create(2020, 1, 1),
                term: 60,
                mileage: 100000,
                annual_mileage: 13000,
                price: 23456,
                deposit: 3000,
                credit_rating: 'excellent',
                is_vat_applicable: false,
            )
        ];

        $provider = FinanceServiceHelper::initializeForSite();
        $results = $provider->batchRequest(collect($batch));

        // assert that the batch of vat applicable vehicles gets CashValuesAreVatExclusive in the request
        Http::assertSent(fn (Request $request) => array_key_exists('CashValuesAreVatExclusive', $request['Parameters'])
            && $request['Parameters']['CashValuesAreVatExclusive'] == true);

        // and that DepositTaxPayable from the response is carried through into the FinanceResult
        $vehicleQuotes = $results->first();
        $pcp = $vehicleQuotes->first(fn ($r) => $r->finance_type->value === 'PCP');
        $this->assertEquals(600, $pcp->deposit_tax_payable);
    }

    public function testBatchRequestKeysResultsByUuidWhenRegistrationNumberIsEmpty()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response(
                $this->batchResponseWithMixedIdentifiers()
            ),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $batch = collect([
            new FinanceRequestData(
                uuid: 'vehicle-with-reg',
                registration_number: 'SD12 ABC',
                cap_id: '1231122',
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'used',
                registration_date: Carbon::create(2020, 1, 1),
                term: 60,
                mileage: 10000,
                annual_mileage: 10000,
                price: 15000,
                deposit: 1500,
                credit_rating: 'excellent',
            ),
            new FinanceRequestData(
                uuid: 'vehicle-no-reg',
                registration_number: '',
                cap_id: '9876543',
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: null,
                term: 60,
                mileage: 0,
                annual_mileage: 10000,
                price: 25000,
                deposit: 2500,
                credit_rating: 'excellent',
            ),
        ]);

        $result = $provider->batchRequest($batch);

        $this->assertCount(2, $result);
        // Vehicle with registration number is keyed by reg
        $this->assertArrayHasKey('SD12 ABC', $result->toArray());
        // Vehicle without registration number is keyed by uuid via response Id
        $this->assertArrayHasKey('vehicle-no-reg', $result->toArray());
    }

    public function testBatchRequestKeysByRegWhenFirstProductResultErrored()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response(
                $this->batchResponseWithErroredFirstProduct()
            ),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $batch = collect([
            new FinanceRequestData(
                uuid: '8a4290bb9db45381119de2b374f00ad0',
                registration_number: 'MB23 OUK',
                cap_id: null,
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'used',
                registration_date: Carbon::create(2023, 3, 15),
                term: 36,
                mileage: 23482,
                annual_mileage: 10000,
                price: 20495,
                deposit: 4099,
                credit_rating: 'excellent',
            ),
        ]);

        $result = $provider->batchRequest($batch);

        $this->assertCount(1, $result);
        $this->assertArrayHasKey('MB23 OUK', $result->toArray());

        $quotes = $result->get('MB23 OUK');
        $this->assertEquals(1, $quotes->count());
        $cs = $quotes->filter(fn ($q) => $q->finance_type->value === 'CS')->first();
        $this->assertNotNull($cs);
        $this->assertEquals(553.12, $cs->monthly_price);
    }

    public function testBatchRequestStillKeysByUuidWhenCodeweaversEnrichesResponseRegistration()
    {
        // Regression: new VIN-only vehicles where Codeweavers resolves a registration number
        // server-side. The response Vehicle.RegistrationNumber must NOT be used as the result
        // key (it doesn't match what RunQuoteRequest keyed the batch by). Result must be keyed
        // by the round-tripped Id (= uuid).
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response(
                $this->batchResponseWithEnrichedRegistration()
            ),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $batch = collect([
            new FinanceRequestData(
                uuid: 'new-vin-only-vehicle',
                registration_number: '',
                cap_id: '',
                cap_code: null,
                dealer_id: 'abc123',
                engine_size: 1999,
                condition: 'new',
                registration_date: null,
                term: 60,
                mileage: 0,
                annual_mileage: 10000,
                price: 25000,
                deposit: 2500,
                credit_rating: 'excellent',
                vin: 'WVWZZZ1JZ3W386752',
            ),
        ]);

        $result = $provider->batchRequest($batch);

        // Must be keyed by uuid (round-tripped Id), not by the registration number Codeweavers
        // enriched into the response Vehicle.
        $this->assertCount(1, $result);
        $this->assertArrayHasKey('new-vin-only-vehicle', $result->toArray());
        $this->assertArrayNotHasKey('ENRICHED99', $result->toArray());
    }

    public function testVehicleTypeCar()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            is_vat_applicable: false,
            vehicle_type: 'car',
        ));

        Http::assertSent(fn (Request $request) => $request['VehicleRequests'][0]['Vehicle']['Type'] == 'Car');
    }

    public function testVehicleTypeLcv()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            is_vat_applicable: false,
            vehicle_type: 'lcv',
        ));

        Http::assertSent(fn (Request $request) => $request['VehicleRequests'][0]['Vehicle']['Type'] == 'Lcv');
    }

    public function testVehicleTypeBike()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        $this->seed(CodeweaversVATSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-codeweavers-send-vat', true);

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 100000,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            is_vat_applicable: false,
            vehicle_type: 'motorcycle',
        ));

        Http::assertSent(fn (Request $request) => $request['VehicleRequests'][0]['Vehicle']['Type'] == 'Bike');
    }

    public function testIdentifierForNewVehicleWithCapId()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: '1231122',
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 0,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            vin: '1HGBH41JXMN109186',
            is_new: true,
        ));

        Http::assertSent(fn (Request $request) =>
            $request['VehicleRequests'][0]['Vehicle']['IdentifierType'] === 'CapShortCode'
            && $request['VehicleRequests'][0]['Vehicle']['Identifier'] === '1231122');
    }

    public function testIdentifierForNewVehicleFallsBackToVinNotRegistration()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: null,
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 0,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            vin: '1HGBH41JXMN109186',
            is_new: true,
        ));

        Http::assertSent(fn (Request $request) =>
            $request['VehicleRequests'][0]['Vehicle']['IdentifierType'] === 'VIN'
            && $request['VehicleRequests'][0]['Vehicle']['Identifier'] === '1HGBH41JXMN109186');
    }

    public function testIdentifierForUsedVehicleWithoutCapIdUsesRegistration()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: null,
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'used',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 10000,
            annual_mileage: 13000,
            price: 15000,
            deposit: 1500,
            credit_rating: 'excellent',
            vin: '1HGBH41JXMN109186',
            is_new: false,
        ));

        Http::assertSent(fn (Request $request) =>
            $request['VehicleRequests'][0]['Vehicle']['IdentifierType'] === 'VRM'
            && $request['VehicleRequests'][0]['Vehicle']['Identifier'] === 'SD12 ABC');
    }

    public function testIdentifierForNewVehicleWithOnlyRegistrationIsNull()
    {
        Http::fake([
            "https://services.codeweavers.net/public/v3/jsonfinance/calculate" => Http::response($this->response()),
            "*" => Http::response([], 400),
        ]);

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');

        $provider = FinanceServiceHelper::initializeForSite();

        $provider->calculate(new FinanceRequestData(
            uuid: 'abc123',
            registration_number: 'SD12 ABC',
            cap_id: null,
            cap_code: null,
            dealer_id: 'abc123',
            engine_size: 1999,
            condition: 'new',
            registration_date: Carbon::create(2020, 1, 1),
            term: 60,
            mileage: 0,
            annual_mileage: 13000,
            price: 23456,
            deposit: 3000,
            credit_rating: 'excellent',
            vin: null,
            is_new: true,
        ));

        Http::assertSent(fn (Request $request) =>
            $request['VehicleRequests'][0]['Vehicle']['IdentifierType'] === null
            && $request['VehicleRequests'][0]['Vehicle']['Identifier'] === null);
    }

    private function responseTermsAndConditions(): array
    {
        return [
            'TermsAndConditions' => 'lorem ipsum'
        ];
    }

    private function responseTermsAndConditionsEmpty(): array
    {
        return [];
    }

    private function responseWithQuoteReference()
    {
        return [
            'VehicleResults' => [
                [
                    'FinanceProductResults' => [
                        [
                            'Product' => [
                                'Type' => 'HP',
                                'Name' => 'test HP',
                            ],
                            'Quote' => [
                                'QuoteReference' => 'foo',
                                'AllInclusiveRegularPayment' => 456,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [
                                    ['Amount' => 132],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                ],
                                'Fees' => [
                                    [
                                        'Amount' => 456,
                                        'DisplayText' => 'bar',
                                        'FeeType' => 'Admin',
                                        'Profile' => 'foo',
                                        'ExternalIdentifier' => 'baz'
                                    ],
                                ],
                            ]
                        ]
                    ],
                ],
            ]
        ];
    }

    private function response(): array
    {
        return [
            'VehicleResults' => [
                [
                    'FinanceProductResults' => [
                        [
                            'Product' => [
                                'Type' => 'Hire Purchase',
                                'Name' => 'test HP',
                            ],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 555,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'CashDeposit' => 3000,
                                'DepositTaxPayable' => 600,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [
                                    ['Amount' => 132],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                ],
                                'Fees' => [
                                    [
                                        'Amount' => 456,
                                        'DisplayText' => 'bar',
                                        'FeeType' => 'Admin',
                                        'Profile' => 'foo',
                                        'ExternalIdentifier' => 'baz'
                                    ],
                                ],
                            ]
                        ],
                        [
                            'Product' => [
                                'Type' => 'PCP',
                                'Name' => 'test',
                            ],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 123,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'CashDeposit' => 3000,
                                'Deposit' => 3000,
                                'DepositTaxPayable' => 600,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [
                                    [
                                        'Amount' => 132,
                                        'NumberOfPayments' => 1,
                                    ],
                                    [
                                        'Amount' => 123,
                                        'NumberOfPayments' => 58,
                                    ],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                ],
                                'Fees' => [
                                    [
                                        'Amount' => 456,
                                        'DisplayText' => 'bar',
                                        'FeeType' => 'Admin',
                                        'Profile' => 'foo',
                                        'ExternalIdentifier' => 'baz'
                                    ],
                                ],
                            ]
                        ]
                    ],
                ],
            ]
        ];
    }

    private function responseHp()
    {
        return [
            'VehicleResults' => [
                [
                    'FinanceProductResults' => [
                        [
                            'Product' => [
                                'Type' => 'HP',
                                'Name' => 'test HP',
                            ],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 456,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [
                                    ['Amount' => 132],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                ],
                                'Fees' => [
                                    [
                                        'Amount' => 456,
                                        'DisplayText' => 'bar',
                                        'FeeType' => 'Admin',
                                        'Profile' => 'foo',
                                        'ExternalIdentifier' => 'baz'
                                    ],
                                ],
                            ]
                        ]
                    ],
                ],
            ]
        ];
    }

    private function batchResponseWithEnrichedRegistration(): array
    {
        return [
            'VehicleResults' => [
                [
                    'Id' => 'new-vin-only-vehicle',
                    'FinanceProductResults' => [
                        [
                            'Product' => ['Type' => 'PCP', 'Name' => 'test PCP'],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 123,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'CashDeposit' => 3000,
                                'Deposit' => 3000,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [['Amount' => 123, 'NumberOfPayments' => 58]],
                                'Fees' => [],
                            ],
                            'Vehicle' => [
                                // Codeweavers resolved the VIN and enriched the response with
                                // a registration number we never sent.
                                'RegistrationNumber' => 'ENRICHED99',
                                'IdentifierType' => 'VIN',
                                'Identifier' => 'WVWZZZ1JZ3W386752',
                                'IsNew' => true,
                            ],
                        ],
                    ],
                ],
            ],
        ];
    }

    private function batchResponseWithMixedIdentifiers(): array
    {
        $quoteTemplate = [
            'AllInclusiveRegularPayment' => 123,
            'Term' => 60,
            'Apr' => 13,
            'TotalDeposit' => 3000,
            'CashDeposit' => 3000,
            'Deposit' => 3000,
            'FinalPayment' => 1200,
            'RateOfInterest' => 12,
            'CashPrice' => 7000,
            'TotalAmountPayable' => 8393.68,
            'Payments' => [['Amount' => 123, 'NumberOfPayments' => 58]],
            'Fees' => [],
        ];

        return [
            'VehicleResults' => [
                [
                    'Id' => 'SD12 ABC',
                    'FinanceProductResults' => [
                        [
                            'Product' => ['Type' => 'PCP', 'Name' => 'test PCP'],
                            'Quote' => $quoteTemplate,
                            'Vehicle' => [
                                'RegistrationNumber' => 'SD12 ABC',
                                'IdentifierType' => 'VRM',
                                'Identifier' => 'SD12 ABC',
                                'IsNew' => false,
                            ],
                        ],
                    ],
                ],
                [
                    'Id' => 'vehicle-no-reg',
                    'FinanceProductResults' => [
                        [
                            'Product' => ['Type' => 'PCP', 'Name' => 'test PCP'],
                            'Quote' => $quoteTemplate,
                            'Vehicle' => [
                                'RegistrationNumber' => null,
                                'IdentifierType' => 'CapShortCode',
                                'Identifier' => '9876543',
                                'IsNew' => true,
                            ],
                        ],
                    ],
                ],
            ],
        ];
    }

    private function batchResponseWithErroredFirstProduct(): array
    {
        return [
            'VehicleResults' => [
                [
                    'Id' => 'MB23 OUK',
                    'FinanceProductResults' => [
                        [
                            'Key' => 'PCP',
                            'HasError' => true,
                            'Error' => [
                                'DealerMessage' => 'Please contact us directly for finance information.',
                                'TechnicalMessage' => 'Inception age out of range',
                                'Code' => 51172,
                            ],
                            'Product' => ['Type' => 'PCP', 'Name' => 'Personal Contract Purchase'],
                        ],
                        [
                            'Key' => 'CS',
                            'HasError' => false,
                            'Product' => ['Type' => 'Conditional Sale', 'Name' => 'Conditional Sale'],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 553.12,
                                'Term' => 36,
                                'Apr' => 13.9,
                                'TotalDeposit' => 4099,
                                'CashDeposit' => 4099,
                                'Deposit' => 4099,
                                'FinalPayment' => 553.12,
                                'RateOfInterest' => 7.15,
                                'CashPrice' => 20495,
                                'TotalAmountPayable' => 24011.32,
                                'Payments' => [['Amount' => 553.12, 'NumberOfPayments' => 36]],
                                'Fees' => [],
                            ],
                            'Vehicle' => [
                                'IdentifierType' => 'Vrm',
                                'Identifier' => 'MB23 OUK',
                                'RegistrationNumber' => 'MB23 OUK',
                                'IsNew' => false,
                            ],
                        ],
                    ],
                ],
            ],
        ];
    }

    private function responsePcp()
    {
        return [
            'VehicleResults' => [
                [
                    'FinanceProductResults' => [
                        [
                            'Product' => [
                                'Type' => 'PCP',
                                'Name' => 'test PCP',
                            ],
                            'Quote' => [
                                'AllInclusiveRegularPayment' => 789,
                                'Term' => 60,
                                'Apr' => 13,
                                'TotalDeposit' => 3000,
                                'FinalPayment' => 1200,
                                'RateOfInterest' => 12,
                                'CashPrice' => 7000,
                                'TotalAmountPayable' => 8393.68,
                                'Payments' => [
                                    ['Amount' => 132],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                    ['Amount' => 123],
                                ],
                                'Fees' => [
                                    [
                                        'Amount' => 456,
                                        'DisplayText' => 'bar',
                                        'FeeType' => 'Admin',
                                        'Profile' => 'foo',
                                        'ExternalIdentifier' => 'baz'
                                    ],
                                ],
                            ]
                        ]
                    ],
                ],
            ]
        ];
    }
}
