<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use Carbon\Carbon;
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(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 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 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();
        $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);
    }

    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 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');
    }

    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,
                                '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,
                                '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 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' => 'vehicle-with-reg',
                    '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 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'
                                    ],
                                ],
                            ]
                        ]
                    ],
                ],
            ]
        ];
    }
}
