<?php

namespace Tests\Tenant;

use App\Crm\Config\WebLeadsConfig;
use App\Facades\Settings;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Mtc\Crm\Facades\Enquiries;
use Mtc\Crm\Models\Enquiry;
use Mtc\Crm\Models\EnquiryAction;
use Mtc\Crm\Models\FormQuestion;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleValuation;
use Mtc\Crm\Models\EnquiryType;
use Mtc\Crm\Models\Form;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class WebLeadsCrmTest extends TenantTestCase
{
    use UserForTenant;

    public function testConfig()
    {
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'Enabled',
            'config_key' => 'crm-webleads-enabled',
            'type' => 'boolean',
            'value' => true,
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'API Key',
            'config_key' => 'crm-webleads-api-key',
            'type' => 'string',
            'value' => 'foo_api_key',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'API Domain',
            'config_key' => 'crm-webleads-api-domain',
            'type' => 'string',
            'value' => 'https://foo.com',
        ]);

        /** @var WebLeadsConfig $config */
        $config = App::make(WebLeadsConfig::class);
        $this->assertTrue($config->enabled());
        $this->assertEquals('https://foo.com', $config->apiDomain());
        $this->assertEquals('foo_api_key', $config->apiKey());
    }

    public function testSendLead()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "description"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'Parker'],
                $q3->id => ['answer' => '00000111222'],
                $q4->id => ['answer' => 'foo@bar.com'],
                $q5->id => ['answer' => 'my_message'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) use ($enquiry) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['apikey'] === 'foo_api_key'
                && $request['enquiry']['contact']['firstname'] === 'Peter'
                && $request['enquiry']['contact']['surname'] === 'Parker'
                && $request['enquiry']['contact']['email'] === 'foo@bar.com'
                && $request['enquiry']['contact']['phone'] === '00000111222'
                && $request['enquiry']['seeks']['notes'] === 'description: my_message.'
                && $request['enquiry']['lead']['idnumber'] === $enquiry->id
                && $request['enquiry']['lead']['branch'] === 'fallback-dealer-123';
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'webleads')->get());
    }

    public function testSendLeadForVehicle()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "notes"]]);

        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $dealership = Dealership::factory()->create([
            'data' => ['webleads-dealer-id' => 'dealer-456']
        ]);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'dealership_id' => $dealership->id,
            'type' => 'car',
            'is_new' => 0,
            'price' => 12345,
            'registration_number' => 'FO25 FAZ',
            'vrm_condensed' => 'FO25FAZ',
            'uuid' => 'test-uuid-123',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'Parker'],
                $q3->id => ['answer' => '00000111222'],
                $q4->id => ['answer' => 'foo@bar.com'],
                $q5->id => ['answer' => 'my_message'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $vehicle->id,
            'object_type' => $vehicle->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['apikey'] === 'foo_api_key'
                && $request['enquiry']['contact']['firstname'] === 'Peter'
                && $request['enquiry']['contact']['surname'] === 'Parker'
                && $request['enquiry']['contact']['email'] === 'foo@bar.com'
                && $request['enquiry']['contact']['phone'] === '00000111222'
                && $request['enquiry']['seeks']['make'] === 'Audi'
                && $request['enquiry']['seeks']['model'] === 'A6'
                && $request['enquiry']['seeks']['regnumber'] === 'FO25FAZ'
                && $request['enquiry']['seeks']['stocknumber'] === 'test-uuid-123'
                && $request['enquiry']['lead']['branch'] === 'dealer-456';
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'webleads')->get());
    }

    public function testSendLeadForVehicleWithFallbackDealer()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        // Dealership without webleads-dealer-id
        $dealership = Dealership::factory()->create([
            'data' => []
        ]);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'dealership_id' => $dealership->id,
            'type' => 'car',
            'is_new' => 0,
            'price' => 12345,
            'vrm_condensed' => 'FO25FAZ',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $vehicle->id,
            'object_type' => $vehicle->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            // When no dealer ID on dealership, fallback should be used
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['branch'] === 'fallback-dealer-123';
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'webleads')->get());
    }

    public function testSendLeadForValuation()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "notes"]]);

        $valuation = VehicleValuation::query()->create([
            'provider' => 'foo',
            'registration' => 'FO25FAZ',
            'mileage' => 25000,
            'make' => 'Ford',
            'model' => 'Focus',
            'average_price' => 99448,
            'cosmetic_condition' => 'good',
            'date_of_registration' => '2020-06-15',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'Parker'],
                $q3->id => ['answer' => '00000111222'],
                $q4->id => ['answer' => 'foo@bar.com'],
                $q5->id => ['answer' => 'my_message'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $valuation->id,
            'object_type' => $valuation->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['tradein']['registration'] === 'FO25FAZ'
                && $request['enquiry']['tradein']['make'] === 'Ford'
                && $request['enquiry']['tradein']['model'] === 'Focus'
                && $request['enquiry']['tradein']['mileage'] == 25000
                && $request['enquiry']['tradein']['year'] === '2020';
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'webleads')->get());
    }

    public function testSendLeadWithVehicleAndValuation()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $dealership = Dealership::factory()->create([
            'data' => ['webleads-dealer-id' => 'dealer-456']
        ]);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'dealership_id' => $dealership->id,
            'type' => 'car',
            'is_new' => 0,
            'registration_number' => 'FO25 FAZ',
            'uuid' => 'test-uuid-123',
        ]);

        $valuation = VehicleValuation::query()->create([
            'provider' => 'foo',
            'registration' => 'XX25YYY',
            'mileage' => 50000,
            'make' => 'Ford',
            'model' => 'Focus',
            'average_price' => 8000,
            'date_of_registration' => '2019-03-10',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $vehicle->id,
            'object_type' => $vehicle->getMorphClass(),
        ]);
        $enquiry->objects()->create([
            'object_id' => $valuation->id,
            'object_type' => $valuation->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                // Vehicle data in seeks
                && $request['enquiry']['seeks']['make'] === 'Audi'
                && $request['enquiry']['seeks']['model'] === 'A6'
                && $request['enquiry']['seeks']['regnumber'] === 'FO25FAZ'
                // Valuation data in tradein
                && $request['enquiry']['tradein']['registration'] === 'XX25YYY'
                && $request['enquiry']['tradein']['make'] === 'Ford'
                && $request['enquiry']['tradein']['model'] === 'Focus'
                && $request['enquiry']['tradein']['mileage'] == 50000
                && $request['enquiry']['tradein']['year'] === '2019';
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'webleads')->get());
    }

    public function testSendLeadWithPreferredContactMethodsAsCommaSeparatedString()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "preferredContactMethods"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'email,sms,post,phone'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['mkagree']['dealersms'] === true
                && $request['mkagree']['dealeremail'] === true
                && $request['mkagree']['dealerletter'] === true
                && $request['mkagree']['dealerphone'] === true
                && $request['mkagree']['salessms'] === true
                && $request['mkagree']['salesemail'] === true
                && $request['mkagree']['salesletter'] === true
                && $request['mkagree']['salesphone'] === true;
        });
    }

    public function testSendLeadWithPreferredContactMethodsAsArray()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "preferredContactMethods"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => ['email', 'sms']],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['mkagree']['dealersms'] === true
                && $request['mkagree']['dealeremail'] === true
                && $request['mkagree']['dealerletter'] === null
                && $request['mkagree']['dealerphone'] === null;
        });
    }

    public function testSendLeadWithPartialPreferredContactMethods()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "preferredContactMethods"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'email,post'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['mkagree']['dealeremail'] === true
                && $request['mkagree']['dealerletter'] === true
                && $request['mkagree']['dealersms'] === null
                && $request['mkagree']['dealerphone'] === null
                && $request['mkagree']['serviceemail'] === true
                && $request['mkagree']['serviceletter'] === true
                && $request['mkagree']['servicesms'] === null
                && $request['mkagree']['servicephone'] === null;
        });
    }

    public function testSendLeadWithNoMarketingOptIn()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['mkagree']['dealersms'] === null
                && $request['mkagree']['dealeremail'] === null
                && $request['mkagree']['dealerletter'] === null
                && $request['mkagree']['dealerphone'] === null;
        });
    }

    public function testSendLeadWithSourceFromEnquiryType()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $enquiryType = EnquiryType::factory()->create([
            'data' => [
                'webleads_form_type' => 'veh',
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'type_id' => $enquiryType->id,
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['source'] === 'VEH'
                && $request['enquiry']['contact']['source'] === 'WEB';
        });
    }

    public function testSendLeadWithDefaultSourceWhenNoEnquiryType()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'type_id' => null,
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['source'] === 'GEN'
                && $request['enquiry']['contact']['source'] === 'WEB';
        });
    }

    public function testSendLeadForNewVehicle()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $make = VehicleMake::factory()->create(['name' => 'BMW']);
        $model = VehicleModel::factory()->create(['name' => '3 Series']);
        $dealership = Dealership::factory()->create([
            'data' => ['webleads-dealer-id' => 'dealer-789']
        ]);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'dealership_id' => $dealership->id,
            'type' => 'car',
            'is_new' => 1,
            'vrm_condensed' => 'AB12CDE',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $vehicle->id,
            'object_type' => $vehicle->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['seeks']['newused'] === 'New'
                && $request['enquiry']['seeks']['make'] === 'BMW'
                && $request['enquiry']['seeks']['model'] === '3 Series';
        });
    }

    public function testSendLeadForUsedVehicle()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $make = VehicleMake::factory()->create(['name' => 'Mercedes']);
        $model = VehicleModel::factory()->create(['name' => 'C Class']);
        $dealership = Dealership::factory()->create([
            'data' => ['webleads-dealer-id' => 'dealer-999']
        ]);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'dealership_id' => $dealership->id,
            'type' => 'car',
            'is_new' => 0,
            'vrm_condensed' => 'XY67ZZZ',
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);
        $enquiry->objects()->create([
            'object_id' => $vehicle->id,
            'object_type' => $vehicle->getMorphClass(),
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['seeks']['newused'] === 'Used'
                && $request['enquiry']['seeks']['make'] === 'Mercedes'
                && $request['enquiry']['seeks']['model'] === 'C Class';
        });
    }

    public function testSendLeadWithOriginFromForm()
    {
        $this->addSettingsAndHttpFake();

        $form = Form::factory()->create(['name' => 'Vehicle Enquiry Form']);

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'form_id' => $form->id,
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['origin'] === 'Vehicle Enquiry Form';
        });
    }

    public function testSendLeadWithEmptyOriginWhenNoForm()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'form_id' => null,
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['origin'] === '';
        });
    }

    public function testSendLeadWithAddressFieldsInNotes()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "address.address-one"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "address.address-two"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "address.postcode"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => '123 Main Street'],
                $q4->id => ['answer' => 'Apartment 4B'],
                $q5->id => ['answer' => 'AB12 3CD'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            $notes = $request['enquiry']['seeks']['notes'];

            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && Str::contains($notes, 'address-one: 123 Main Street')
                && Str::contains($notes, 'address-two: Apartment 4B')
                && Str::contains($notes, 'postcode: AB12 3CD');
        });
    }

    public function testSendLeadWithVehicleFieldsInNotes()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "vehicle.serialnumber"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "vehicle.chassisnumber"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "vehicle.registrationnumber"]]);
        $q6 = FormQuestion::factory()->create(['data' => ["webleads-field" => "vehicle.yearofmanufacture"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'WVWZZZ3CZWE123456'],
                $q4->id => ['answer' => 'CH987654321'],
                $q5->id => ['answer' => 'AB12 XYZ'],
                $q6->id => ['answer' => '2023'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            $notes = $request['enquiry']['seeks']['notes'];

            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && Str::contains($notes, 'serialnumber: WVWZZZ3CZWE123456')
                && Str::contains($notes, 'chassisnumber: CH987654321')
                && Str::contains($notes, 'registrationnumber: AB12 XYZ')
                && Str::contains($notes, 'yearofmanufacture: 2023');
        });
    }

    public function testSendLeadWithDescriptionInNotes()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "description"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'I am interested in this vehicle'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            $notes = $request['enquiry']['seeks']['notes'];

            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && Str::contains($notes, 'description: I am interested in this vehicle');
        });
    }

    public function testSendLeadWithDynamicSourceFromFormQuestion()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "source"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'svc'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['source'] === 'SVC'
                && $request['enquiry']['contact']['source'] === 'WEB';
        });
    }

    public function testSendLeadWithDynamicSourceOverridesEnquiryType()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "source"]]);

        $enquiryType = EnquiryType::factory()->create([
            'data' => [
                'webleads_form_type' => 'veh',
            ],
        ]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'fin'],
            ],
            'type_id' => $enquiryType->id,
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && $request['enquiry']['lead']['source'] === 'FIN';
        });
    }

    public function testSendLeadWithMixedFieldsInNotes()
    {
        $this->addSettingsAndHttpFake();

        $q1 = FormQuestion::factory()->create(['data' => ["webleads-field" => "firstname"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["webleads-field" => "email"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["webleads-field" => "address.postcode"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["webleads-field" => "vehicle.serialnumber"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["webleads-field" => "description"]]);

        $enquiry = Enquiry::factory()->create([
            'email' => 'foo@bar.com',
            'details' => [
                $q1->id => ['answer' => 'Peter'],
                $q2->id => ['answer' => 'foo@bar.com'],
                $q3->id => ['answer' => 'AB12 3CD'],
                $q4->id => ['answer' => 'WVWZZZ3CZWE123456'],
                $q5->id => ['answer' => 'Please contact me ASAP'],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(function (Request $request) {
            $notes = $request['enquiry']['seeks']['notes'];

            return Str::contains($request->url(), 'https://foo.com/tramo/leads-v1/generic.json')
                && Str::contains($notes, 'postcode: AB12 3CD')
                && Str::contains($notes, 'serialnumber: WVWZZZ3CZWE123456')
                && Str::contains($notes, 'description: Please contact me ASAP');
        });
    }

    private function addSettingsAndHttpFake()
    {
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'Enabled',
            'config_key' => 'crm-webleads-enabled',
            'type' => 'boolean',
            'value' => true,
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'API Key',
            'config_key' => 'crm-webleads-api-key',
            'type' => 'string',
            'value' => 'foo_api_key',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'API Domain',
            'config_key' => 'crm-webleads-api-domain',
            'type' => 'string',
            'value' => 'https://foo.com',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'WebLeads',
            'name' => 'Fallback Dealer ID',
            'config_key' => 'crm-webleads-fallback-dealer-id',
            'type' => 'string',
            'value' => 'fallback-dealer-123',
        ]);

        Http::fake([
            '*' => Http::response([
                'message' => 'Lead created successfully',
                'lead_id' => 'WL123456',
            ], 200),
        ]);
    }
}
