<?php

namespace Tests\Unit;

use App\Facades\Settings;
use Carbon\Carbon;
use Database\Seeders\Tenant\EnquiryMaxSettingSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Mockery\MockInterface;
use Mtc\Crm\Facades\Enquiries;
use Mtc\Crm\Facades\Forms;
use Mtc\Crm\Models\Enquiry;
use Mtc\Crm\Models\EnquiryAction;
use Mtc\Crm\Models\FormQuestion;
use Mtc\Crm\Models\FormSection;
use Mtc\MercuryDataModels\Contracts\LocatingServiceEngine;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Form;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\PostcodeGeo;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleAttribute;
use Mtc\MercuryDataModels\VehicleAttributeValue;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleOffer;
use Mtc\MercuryDataModels\VehicleValuation;
use Tests\TestCase;

class SendToEnquiryMaxTest extends TestCase
{
    use RefreshDatabase;

    protected $tenancy = true;

    public function testSendEnquiry()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create();
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

        $this->assertStringContainsString('1123', $enquiry_max->successDetails());
    }

    public function testSkipsProcessed()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create();
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => Carbon::now(),
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

    }
    public function testSkipsTooManyAttempts()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create();
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'attempts' => 3,
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

    }


    public function testGetFormFields()
    {
        $fields = Enquiries::makeAction('send-to-enquiry-max')->formAdditionalDataFields();

        $this->assertIsArray($fields);
        $this->assertArrayHasKey('fallback-dealership', $fields);
    }

    public function testGetDealershipFields()
    {
        $fields = Enquiries::makeAction('send-to-enquiry-max')->dealershipAdditionalDataFields();

        $this->assertIsArray($fields);
        $this->assertArrayHasKey('enquiry-max-dealership', $fields);
    }

    public function testGetFormQuestionDataFields()
    {
        $fields = Enquiries::makeAction('send-to-enquiry-max')->formQuestionDataFields();
        $this->assertArrayHasKey('enquiry-max-field', $fields);
        $this->assertArrayHasKey('type', $fields['enquiry-max-field']);
        $this->assertArrayHasKey('label', $fields['enquiry-max-field']);
        $this->assertArrayHasKey('choices', $fields['enquiry-max-field']);
    }

    public function testVehicleDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 0,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);
        $enquiry = Enquiry::factory()->create([
            'reason_id' => $vehicle->id,
            'reason_type' => 'vehicle'
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['vehicleOfInterest']['isUsed'] === 1
                && $request['vehicleOfInterest']['price'] === 23450
                && $request['vehicleOfInterest']['make'] === 'Ford'
                && $request['vehicleOfInterest']['model'] === 'Raptor'
                && $request['vehicleOfInterest']['derivative'] === '5.6l V6 Extreme'
                && $request['vehicleOfInterest']['vrm'] === 'AB60 DEV'
                && $request['vehicleOfInterest']['fuelType'] === 'Petrol'
                && $request['vehicleOfInterest']['vehicleIdentificationCode'] === '182371283'
                && $request['vehicleOfInterest']['stockNumber'] === $vehicle->id
                && $request['vehicleOfInterest']['odometer']['currentValue'] === 123000;
        });
    }

    public function testCustomerDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $q1 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "bestTimeToCall"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "preferedContactMethod"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "homeTelephoneNumber"]]);
        $q6 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "emailAddress"]]);
        $q7 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.post"]]);
        $q8 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.phone"]]);
        $q9 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.sms"]]);
        $q10 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.email"]]);
        $q11 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "appointmentDateTime"]]);

        $enquiry = Enquiry::factory()->create([
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'Parker'],
                $q3->id => ['answer' => 'PM'],
                $q4->id => ['answer' => 'email'],
                $q5->id => ['answer' => '1231231122'],
                $q6->id => ['answer' => 'jdoe@test.com'],
                $q7->id => ['answer' => 0],
                $q8->id => ['answer' => 0],
                $q9->id => ['answer' => 0],
                $q10->id => ['answer' => 1],
                $q11->id => ['answer' => '2022-04-22'],
            ],
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['customer']['forename'] === 'Peter'
                && $request['customer']['surname'] === 'Parker'
                && $request['customer']['bestTimeToCall'] === 'PM'
                && $request['customer']['preferedContactMethod'] === 'email'
                && $request['customer']['homeTelephoneNumber'] === '1231231122'
                && $request['customer']['emailAddress'] === 'jdoe@test.com'
                && $request['customer']['marketingPreferences']['post'] === 'false'
                && $request['customer']['marketingPreferences']['phone'] === 'false'
                && $request['customer']['marketingPreferences']['sms'] === 'false'
                && $request['customer']['marketingPreferences']['email'] === 'true'
                && $request['appointment']['appointmentDateTime'] === '2022-04-22';
        });
    }

    public function testMiscDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $q1 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_source"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_medium"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_campaign"]]);

        $enquiry = Enquiry::factory()->create([
            'details' => [
                $q1->id => ['answer' => 'answer source'],
                $q2->id => ['answer' => 'answer medium'],
                $q3->id => ['answer' => 'answer campaign'],
            ],
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['Misc']['UTM Source'] === 'answer source'
                && $request['Misc']['UTM Medium'] === 'answer medium'
                && $request['Misc']['UTM Campaign'] === 'answer campaign';
        });
    }

    public function testOfferDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $offer = VehicleOffer::factory()->create([
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Limited',
        ]);

        $enquiry = Enquiry::factory()->create([
            'reason_id' => $offer->id,
            'reason_type' => 'offer'
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['vehicleOfInterest']['isUsed'] === 0
                && $request['vehicleOfInterest']['price'] === 23450
                && $request['vehicleOfInterest']['make'] === 'Ford'
                && $request['vehicleOfInterest']['model'] === 'Raptor'
                && $request['vehicleOfInterest']['derivative'] === '5.6l V6 Limited';
        });
    }


    public function testValuationDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 0,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);

        $vehicle_valuation = VehicleValuation::factory()->create();

        $enquiry_model = config('crm.enquiry_model');
        $enquiry = $enquiry_model::create([
            'ingested_at' => random_int(0, 1) ? Carbon::now()->subMinutes(random_int(0, 2000)) : null,
            'form_id' => random_int(1, 50),
            'email' => 'example@example.com',
            'submitter_id' => null,
            'submitter_type' => null,
            'type_id' => 6,
            'status_id' => random_int(1, 10),
            'title' => 'Title Schmitle',
            'message' => "the medium, per Mcluhan",
            'details' => [],
            'data' => [],
            'assigned_user_id' => random_int(0, 10) ?: null,
            'customer_id' => random_int(0, 10) ?: null,
            'reason_id' => $vehicle->id,
            'reason_type' => 'valuation',
            'valuation_id' => $vehicle_valuation->id
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');

        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle_valuation) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['notes'] === 'Valuation: ' . $vehicle_valuation->retail_price;
        });
    }

    public function testAdjustedValuationDataMapping()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 0,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);

        $vehicle_valuation = VehicleValuation::factory()->create([
            'retail_price' => 64900,
            'adjusted_retail_price' => 69420
        ]);

        $enquiry_model = config('crm.enquiry_model');
        $enquiry = $enquiry_model::create([
            'ingested_at' => random_int(0, 1) ? Carbon::now()->subMinutes(random_int(0, 2000)) : null,
            'form_id' => random_int(1, 50),
            'email' => 'example@example.com',
            'submitter_id' => null,
            'submitter_type' => null,
            'type_id' => 6,
            'status_id' => random_int(1, 10),
            'title' => 'Title Schmitle',
            'message' => "the medium, per Mcluhan",
            'details' => [],
            'data' => [],
            'assigned_user_id' => random_int(0, 10) ?: null,
            'customer_id' => random_int(0, 10) ?: null,
            'reason_id' => $vehicle->id,
            'reason_type' => 'valuation',
            'valuation_id' => $vehicle_valuation->id
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');

        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle_valuation) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead'
                && $request['notes'] !== 'Valuation: ' . $vehicle_valuation->retail_price
                && $request['notes'] === 'Valuation: ' . $vehicle_valuation->adjusted_retail_price;
        });
    }

    public function testFullDetailEnquirySend()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'test');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 0,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEL',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182481',
            'odometer_mi' => 123000,
        ]);

        $q1 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "bestTimeToCall"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "preferedContactMethod"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "homeTelephoneNumber"]]);
        $q6 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "emailAddress"]]);
        $q7 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.post"]]);
        $q8 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.phone"]]);
        $q9 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.sms"]]);
        $q10 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "marketing.email"]]);
        $q11 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "appointmentDateTime"]]);
        $q12 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_source"]]);
        $q13 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_medium"]]);
        $q14 = FormQuestion::factory()->create(['data' => ["enquiry-max-field" => "utm_campaign"]]);

        $enquiry = Enquiry::factory()->create([
            'reason_id' => $vehicle->id,
            'reason_type' => 'vehicle',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'Parker'],
                $q3->id => ['answer' => 'PM'],
                $q4->id => ['answer' => 'email'],
                $q5->id => ['answer' => '1231231122'],
                $q6->id => ['answer' => 'jdoe@test.com'],
                $q7->id => ['answer' => 0],
                $q8->id => ['answer' => 0],
                $q9->id => ['answer' => 0],
                $q10->id => ['answer' => 1],
                $q11->id => ['answer' => '2022-04-22'],
                $q12->id => ['answer' => 'test-utm-source'],
                $q13->id => ['answer' => 'test-utm-medium'],
                $q14->id => ['answer' => 'test-utm-campaign'],
            ],
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://stagingapi.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://stagingapi.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle) {
            return $request->url() === 'https://stagingapi.enquirymax.net/services/v1/2/lead'
                && $request['vehicleOfInterest']['isUsed'] === 1
                && $request['vehicleOfInterest']['price'] === 23450
                && $request['vehicleOfInterest']['make'] === 'Ford'
                && $request['vehicleOfInterest']['model'] === 'Raptor'
                && $request['vehicleOfInterest']['derivative'] === '5.6l V6 Extreme'
                && $request['vehicleOfInterest']['vrm'] === 'AB60 DEL'
                && $request['vehicleOfInterest']['fuelType'] === 'Petrol'
                && $request['vehicleOfInterest']['vehicleIdentificationCode'] === '182481'
                && $request['vehicleOfInterest']['stockNumber'] === $vehicle->id
                && $request['vehicleOfInterest']['odometer']['currentValue'] === 123000
                && $request['customer']['forename'] === 'Peter'
                && $request['customer']['surname'] === 'Parker'
                && $request['customer']['bestTimeToCall'] === 'PM'
                && $request['customer']['preferedContactMethod'] === 'email'
                && $request['customer']['homeTelephoneNumber'] === '1231231122'
                && $request['customer']['emailAddress'] === 'jdoe@test.com'
                && $request['customer']['marketingPreferences']['post'] === 'false'
                && $request['customer']['marketingPreferences']['phone'] === 'false'
                && $request['customer']['marketingPreferences']['sms'] === 'false'
                && $request['customer']['marketingPreferences']['email'] === 'true'
                && $request['appointment']['appointmentDateTime'] === '2022-04-22'
                && $request['Misc']['UTM Source'] === 'test-utm-source'
                && $request['Misc']['UTM Medium'] === 'test-utm-medium'
                && $request['Misc']['UTM Campaign'] === 'test-utm-campaign';
        });
    }

    public function testSendEnquiryToClosestDealership()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'crm-enquiry-max-closest-dealer',
            'value' => true,
            'type' => 'boolean',
        ]);

        $target_latitude = 56.46;
        $target_longitude = -2.96;
        $this->setMockResponseFromLocatingService($target_latitude, $target_longitude);

        Dealership::factory()->create([
            'postcode' => 'AB123LQ',
            'coordinates' => '57.12,-2.09',
            'data' => [
                'enquiry-max-dealership' => 'foo'
            ]
        ]);

        Dealership::factory()->create([
            'postcode' => 'DD13JA',
            'coordinates' => $target_latitude . ',' . $target_longitude,
            'data' => [
                'enquiry-max-dealership' => 'baz'
            ]
        ]);

        Dealership::factory()->create([
            'postcode' => 'G12FF',
            'coordinates' => '55.86,-4.25',
            'data' => [
                'enquiry-max-dealership' => 'bar'
            ]
        ]);

        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create([
            'details' => [
                2 => 'DD13JA'
            ],
            'data' => [
                'questions' => [
                    2 => [
                        'enquiry-max-field' => 'address.postcode'
                    ]
                ]
            ]
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        // we expect to have used the dealer ID corresponding to 'baz'
        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/1/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/3/lead';
        });
    }

    public function testLocationEnquiryWithDealerId()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'crm-enquiry-max-closest-dealer',
            'value' => true,
            'type' => 'boolean',
        ]);

        $dealer_example = Dealership::factory()->create([
            'postcode' => 'AB123LQ',
            'coordinates' => '57.12,-2.09',
            'data' => [
                'enquiry-max-dealership' => 'foo'
            ]
        ]);

        Dealership::factory()->create([
            'postcode' => 'DD13JA',
            'coordinates' => '56.46,-2.96',
            'data' => [
                'enquiry-max-dealership' => 'baz'
            ]
        ]);

        Dealership::factory()->create([
            'postcode' => 'G12FF',
            'coordinates' => '55.86,-4.25',
            'data' => [
                'enquiry-max-dealership' => 'bar'
            ]
        ]);

        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create([
            'details' => [
                2 => 'DD13JA'
            ],
            'data' => [
                'questions' => [
                    2 => [
                        'enquiry-max-field' => 'address.postcode'
                    ]
                ]
            ]
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'dealer-id' => $dealer_example->id
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        // we expect to have used the dealer ID corresponding to 'foo'
        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/1/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/3/lead';
        });
    }

    public function testLocationEnquiryWithFranchiseId()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'crm-enquiry-max-closest-dealer',
            'value' => true,
            'type' => 'boolean',
        ]);

        $target_latitude = 56.46;
        $target_longitude = -2.96;
        $this->setMockResponseFromLocatingService($target_latitude, $target_longitude);

        Dealership::factory()->create([
            'postcode' => 'AB123LQ',
            'coordinates' => '57.12,-2.09',
            'data' => [
                'enquiry-max-dealership' => 'foo'
            ],
            'franchise_id' => 1,
        ]);

        Dealership::factory()->create([
            'postcode' => 'DD13JA',
            'coordinates' => $target_latitude . ',' . $target_longitude,
            'data' => [
                'enquiry-max-dealership' => 'baz'
            ],
            'franchise_id' => 2,
        ]);

        Dealership::factory()->create([
            'postcode' => 'G12FF',
            'coordinates' => '55.86,-4.25',
            'data' => [
                'enquiry-max-dealership' => 'bar'
            ],
            'franchise_id' => 3,
        ]);

        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create([
            'details' => [
                2 => 'DD13JA'
            ],
            'data' => [
                'questions' => [
                    2 => [
                        'enquiry-max-field' => 'address.postcode'
                    ]
                ]
            ]
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'franchise-id' => 3
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        // we expect to have used the dealer ID corresponding to 'bar'
        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/3/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/1/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });
    }

    public function testLocationEnquiryWithFallbackDealership()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'crm-enquiry-max-closest-dealer',
            'value' => true,
            'type' => 'boolean',
        ]);

        Dealership::factory()->create([
            'postcode' => 'AB123LQ',
            'coordinates' => '57.12,-2.09',
            'data' => [
                'enquiry-max-dealership' => 'foo'
            ],
            'franchise_id' => 1,
        ]);

        Dealership::factory()->create([
            'postcode' => 'DD13JA',
            'coordinates' => '56.46,-2.96',
            'data' => [
                'enquiry-max-dealership' => 'baz'
            ],
            'franchise_id' => 2,
        ]);

        Dealership::factory()->create([
            'postcode' => 'G12FF',
            'coordinates' => '55.86,-4.25',
            'data' => [
                'enquiry-max-dealership' => 'bar'
            ],
            'franchise_id' => 3,
        ]);

        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $enquiry = Enquiry::factory()->create([
            'details' => [
                2 => 'NOT_A_VALID_POSTCODE'
            ],
            'data' => [
                'questions' => [
                    2 => [
                        'enquiry-max-field' => 'address.postcode'
                    ]
                ]
            ]
        ]);

        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'foo'
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        // we expect to have used the dealer ID corresponding to 'foo'
        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/1/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/2/lead';
        });

        Http::assertNotSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/v1/3/lead';
        });
    }

    public function testEnquiryMaxVehicleLink()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'vehicles-url-path',
            'type' => 'string',
            'value' => '/vehicle-details/{{MAKE}}/{{MODEL}}/{{SLUG}}',
        ]);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Foo', 'slug' => 'foo']);
        $model = VehicleModel::factory()->create(['name' => 'Faz', 'slug' => 'faz']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
        ]);
        $enquiry = Enquiry::factory()->create([
            'reason_type' => 'vehicle',
            'reason_id' => $vehicle->id,
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        Http::assertSent(function (Request $request) use ($vehicle) {

            if (array_key_exists('link', $request->data())) {
                return $this->assertStringContainsString('/foo/faz/' . $vehicle->slug, $request->data()['link']);
            }

            return true;
        });

        $this->assertStringContainsString('1123', $enquiry_max->successDetails());
    }

    public function testEnquiryMaxOfferLink()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'offers-url-path',
            'type' => 'string',
            'value' => '/vehicle-details/{{MAKE}}/{{MODEL}}/{{SLUG}}O',
        ]);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $offer = VehicleOffer::factory()->create();
        $enquiry = Enquiry::factory()->create([
            'reason_type' => 'offer',
            'reason_id' => $offer->id,
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) {
            return $request->url() === 'https://api.enquirymax.net/services/token'
                && $request['granttype'] === 'client_credentials'
                && $request['clientId'] === 'foo-baz'
                && $request['clientSecret'] === 'baz-bar';
        });

        Http::assertSent(function (Request $request) use ($offer) {

            if (array_key_exists('link', $request->data())) {
                return $this->assertStringContainsString('/make/model/' . $offer->slug, $request->data()['link']);
            }

            return true;
        });

        $this->assertStringContainsString('1123', $enquiry_max->successDetails());
    }

    public function testEnquiryMaxOfferTypeEnabled()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'offers-url-path',
            'type' => 'string',
            'value' => '/vehicle-details/{{MAKE}}/{{MODEL}}/{{SLUG}}O',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'crm-enquiry-max-append-offer-type-to-enquiry-title',
            'type' => 'boolean',
            'value' => true,
        ]);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test1',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Offer',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test2',
        ]);

        $offer = VehicleOffer::factory()->create([
            'form_id' => $form->id,
            'type' => 'offer_type',
        ]);
        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'reason_type' => 'offer',
            'reason_id' => $offer->id,
            'details' => [
                [
                    'id' => 124,
                    'question' => 'test1',
                    'answer' => 'answer1',
                ],
                [
                    'id' => 123,
                    'question' => 'Offer',
                    'answer' => $offer->id,
                ],
                [
                    'id' => 125,
                    'question' => 'test2',
                    'answer' => 'answer2',
                ],
            ],
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        $lead_type_tested = false;

        Http::assertSent(function (Request $request) use (&$lead_type_tested) {
            $request_data = json_decode($request->body(), true);

            if (array_key_exists('leadType', $request_data)) {
                $lead_type_tested = true;
                return $request_data['leadType'] == 'New Car Enquiry - offer_type';
            }

            return false;
        });

        $this->assertTrue($lead_type_tested);
    }

    public function testEnquiryMaxOfferTypeOfferNotFound()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'offers-url-path',
            'type' => 'string',
            'value' => '/vehicle-details/{{MAKE}}/{{MODEL}}/{{SLUG}}O',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'crm-enquiry-max-append-offer-type-to-enquiry-title',
            'type' => 'boolean',
            'value' => true,
        ]);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test1',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Offer',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test2',
        ]);

        $offer = VehicleOffer::factory()->create([
            'form_id' => $form->id,
            'type' => 'offer_type',
        ]);
        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'reason_type' => 'offer',
            'reason_id' => $offer->id + 1,
            'details' => [
                [
                    'id' => 124,
                    'question' => 'test1',
                    'answer' => 'answer1',
                ],
                [
                    'id' => 123,
                    'question' => 'Offer',
                    'answer' => $offer->id + 1,
                ],
                [
                    'id' => 125,
                    'question' => 'test2',
                    'answer' => 'answer2',
                ],
            ],
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        $lead_type_tested = false;

        Http::assertSent(function (Request $request) use (&$lead_type_tested) {
            $request_data = json_decode($request->body(), true);

            if (array_key_exists('leadType', $request_data)) {
                $lead_type_tested = true;
                return $request_data['leadType'] == 'New Car Enquiry';
            }

            return false;
        });

        $this->assertTrue($lead_type_tested);
    }

    public function testEnquiryMaxOfferTypeDisabled()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'offers-url-path',
            'type' => 'string',
            'value' => '/vehicle-details/{{MAKE}}/{{MODEL}}/{{SLUG}}O',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'test',
            'config_key' => 'crm-enquiry-max-append-offer-type-to-enquiry-title',
            'type' => 'boolean',
            'value' => false,
        ]);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $form = Form::factory()->create();
        $section = FormSection::factory()->create(['form_id' => $form->id]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test1',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'Offer',
        ]);

        FormQuestion::factory()->create([
            'form_id' => $form->id,
            'form_section_id' => $section->id,
            'name' => 'test2',
        ]);

        $offer = VehicleOffer::factory()->create([
            'form_id' => $form->id,
            'type' => 'offer_type',
        ]);
        $enquiry = Enquiry::factory()->create([
            'form_id' => $form->id,
            'reason_type' => 'offer',
            'reason_id' => $offer->id,
            'details' => [
                [
                    'id' => 124,
                    'question' => 'test1',
                    'answer' => 'answer1',
                ],
                [
                    'id' => 123,
                    'question' => 'Offer',
                    'answer' => $offer->id,
                ],
                [
                    'id' => 125,
                    'question' => 'test2',
                    'answer' => 'answer2',
                ],
            ],
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        $lead_type_tested = false;

        Http::assertSent(function (Request $request) use (&$lead_type_tested) {
            $request_data = json_decode($request->body(), true);

            if (array_key_exists('leadType', $request_data)) {
                $lead_type_tested = true;
                return $request_data['leadType'] == 'New Car Enquiry';
            }

            return false;
        });

        $this->assertTrue($lead_type_tested);
    }

    public function testLeadTypeUsedCar()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 0,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);
        $enquiry = Enquiry::factory()->create([
            'reason_id' => $vehicle->id,
            'reason_type' => 'vehicle'
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle) {
            if (array_key_exists('leadType', $request->data())) {
                return $request['leadType'] == 'Used Car Enquiry';
            }
        });
    }

    public function testLeadTypeNewCar()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 1,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);
        $enquiry = Enquiry::factory()->create([
            'reason_id' => $vehicle->id,
            'reason_type' => 'vehicle'
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle) {
            if (array_key_exists('leadType', $request->data())) {
                return $request['leadType'] == 'New Car Enquiry';
            }
        });
    }

    public function testLeadTypeNewCarWithStockStatus()
    {
        $this->seed(EnquiryMaxSettingSeeder::class);

        Config::set('services.enquiry-max.mode', 'live');
        Settings::update('crm-enquiry-max-client-id', 'foo-baz');
        Settings::update('crm-enquiry-max-client-secret', 'baz-bar');

        $make = VehicleMake::factory()->create(['name' => 'Ford']);
        $model = VehicleModel::factory()->create(['name' => 'Raptor']);
        $fuel_type = FuelType::factory()->create(['name' => 'Petrol']);
        $vehicle = Vehicle::factory()->create([
            'is_new' => 1,
            'price' => 23450,
            'make_id' => $make->id,
            'model_id' => $model->id,
            'derivative' => '5.6l V6 Extreme',
            'registration_number' => 'AB60 DEV',
            'fuel_type_id' => $fuel_type->id,
            'cap_id' => '182371283',
            'odometer_mi' => 123000,
        ]);


        // TODO: add vehicle attribute value
        // add vehicle attribute for stock_status
        $attribute = VehicleAttribute::factory()->create([
            'name' => 'stock status',
            'model' => 'vehicle',
            'slug' => 'stock_status',
            'type' => 'string',
            'count' => 1
        ]);

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

        $enquiry = Enquiry::factory()->create([
            'reason_id' => $vehicle->id,
            'reason_type' => 'vehicle'
        ]);
        $action = EnquiryAction::factory()->create([
            'action_name' => 'send-to-enquiry-max',
            'data' => [
                'fallback-dealership' => 'baz',
            ],
            'processed_at' => null,
            'failed_at' => null
        ]);

        Storage::fake('file-storage');
        Http::fake([
            'https://api.enquirymax.net/services/token' => Http::response($this->authTokenResponse()),
            'https://api.enquirymax.net/services/v1/*/lead' => Http::response($this->leadResponse()),
            "*" => Http::response([], 400),
        ]);

        $enquiry_max = Enquiries::makeAction('send-to-enquiry-max');
        $enquiry_max->handle($action, $enquiry);

        Http::assertSent(function (Request $request) use ($vehicle) {
            if (array_key_exists('leadType', $request->data())) {
                return $request['leadType'] == 'New Car Enquiry - foo';
            }
        });
    }

    private function setMockResponseFromLocatingService($latitude, $longitude)
    {
        $postcode_geo_model = new PostcodeGeo();
        $postcode_geo_model->latitude = $latitude;
        $postcode_geo_model->longitude = $longitude;

        $this->partialMock(LocatingServiceEngine::class, function (MockInterface $mock) use ($postcode_geo_model) {
            $mock->shouldReceive('find')->andReturn($postcode_geo_model);
        });
    }

    private function authTokenResponse()
    {
        return [
            'accessToken' => 'lorem-ipsum',
            'expiresIn' => 1000,
            'dealers' => [
                [
                    'dealerId' => 1,
                    'dealerName' => 'foo',
                ],
                [
                    'dealerId' => 2,
                    'dealerName' => 'baz',
                ],
                [
                    'dealerId' => 3,
                    'dealerName' => 'bar',
                ],
            ]

        ];
    }

    private function leadResponse()
    {
        return [
            'leadId' => 1123,
        ];
    }
}
