<?php

namespace Tests\Tenant;

use App\Crm\Config\FuseCrmConfig;
use App\Facades\Settings;
use Mtc\MercuryDataModels\VehicleMake;
use App\Services\FuseCrmApi;
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\NewCar;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleModel;
use Mtc\MercuryDataModels\VehicleOffer;
use Mtc\MercuryDataModels\VehicleValuation;
use Mtc\VehicleReservations\Reservation;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class FuseCrmTest extends TenantTestCase
{
    use UserForTenant;

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

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

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client ID',
            'config_key' => 'fuse-crm-client-id',
            'type' => 'string',
            'value' => 'foo_client_id',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client Secret',
            'config_key' => 'fuse-crm-client-secret',
            'type' => 'secret',
            'value' => 'foo_client_secret',
        ]);

        /** @var FuseCrmConfig $config */
        $config = App::make(FuseCrmConfig::class);
        $this->assertFalse($config->enabled());
        $this->assertEquals('https://foo.com', $config->apiDomain());
        $this->assertEquals('foo_client_id', $config->clientId());
        $this->assertEquals('foo_client_secret', $config->clientSecret());
    }

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

        new FuseCrmApi(App::make(FuseCrmConfig::class))->sendLead(new Enquiry(), new EnquiryAction());

        Http::assertSent(fn (Request $request) => $request->url() === 'https://foo.com/api/token'
        && $request->data()['client_id'] == 'foo_client_id'
        && $request->data()['client_secret'] == 'foo_client_secret');
    }

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

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

        $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-fuse',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@bar.com'
            && $request['phone'] === '00000111222'
            && $request['customer_comments'] == 'my_message');

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

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

        $q1 = FormQuestion::factory()->create(['data' => ["fuse-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["fuse-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["fuse-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["fuse-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["fuse-field" => "customer_comments"]]);
        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'type' => 'car',
            'is_new' => 0,
            'price' => 12345,
            'registration_number' => 'FO25 FAZ',
            'vrm_condensed' => 'FO25FAZ',
            'cap_id' => 12311
        ]);

        $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-fuse',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@bar.com'
            && $request['phone'] === '00000111222'
            && $request['car_or_van'] === 'car'
            && $request['sale_type'] === 'Used'
            && $request['vehicle_interest'] === 'Audi'
            && $request['vehicle_model'] === 'A6'
            && $request['vehicle_type'] === 'FO25FAZ'
            && $request['vehicle_cap_id'] == 12311
            && $request['loan_amount'] == 12345
            && $request['reg_number_enquired_on'] === 'FO25 FAZ'
            && $request['customer_comments'] == 'my_message');

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

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

        $q1 = FormQuestion::factory()->create(['data' => ["fuse-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["fuse-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["fuse-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["fuse-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["fuse-field" => "customer_comments"]]);
        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $vehicle = VehicleOffer::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'name' => 'Foo Faz Deluxe',
            'cap_id' => 12311,
        ]);

        $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-fuse',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@bar.com'
            && $request['phone'] === '00000111222'
            && $request['sale_type'] === 'New'
            && $request['vehicle_interest'] === 'Audi'
            && $request['vehicle_model'] === 'A6'
            && $request['vehicle_type'] === 'Foo Faz Deluxe'
            && $request['vehicle_cap_id'] == 12311
            && $request['customer_comments'] == 'my_message');

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

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

        $q1 = FormQuestion::factory()->create(['data' => ["fuse-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["fuse-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["fuse-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["fuse-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["fuse-field" => "customer_comments"]]);
        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $vehicle = NewCar::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'name' => 'Foo Faz Deluxe',
            'price' => 99448
        ]);

        $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-fuse',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@bar.com'
            && $request['phone'] === '00000111222'
            && $request['sale_type'] === 'New'
            && $request['vehicle_interest'] === 'Audi'
            && $request['vehicle_model'] === 'A6'
            && $request['vehicle_type'] === 'Foo Faz Deluxe'
            && $request['loan_amount'] == 99448
            && $request['customer_comments'] == 'my_message');

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

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

        $q1 = FormQuestion::factory()->create(['data' => ["fuse-field" => "forename"]]);
        $q2 = FormQuestion::factory()->create(['data' => ["fuse-field" => "surname"]]);
        $q3 = FormQuestion::factory()->create(['data' => ["fuse-field" => "phone"]]);
        $q4 = FormQuestion::factory()->create(['data' => ["fuse-field" => "email"]]);
        $q5 = FormQuestion::factory()->create(['data' => ["fuse-field" => "customer_comments"]]);
        $valuation = VehicleValuation::query()->create([
            'provider' => 'foo',
            'registration' => 'FO25FAZ',
            'mileage' => 25000,
            'make' => 'Ford',
            'model' => 'Focus',
            'average_price' => 99448,
            'cosmetic_condition' => 'good',
        ]);

        $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-fuse',
            'data' => [],
            'processed_at' => null,
            'failed_at' => null
        ]);

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
                && $request['forename'] === 'Peter'
                && $request['surname'] === 'Parker'
                && $request['email'] === 'foo@bar.com'
                && $request['phone'] === '00000111222'
                && Str::contains($request['customer_comments'], 'Ford')
                && Str::contains($request['customer_comments'], 'Focus')
                && Str::contains($request['customer_comments'], 99448)
                && Str::contains($request['customer_comments'], 'my_message')
                && Str::contains($request['customer_comments'], 'condition good'));

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

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

        $make = VehicleMake::factory()->create(['name' => 'Audi']);
        $model = VehicleModel::factory()->create(['name' => 'A6']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'type' => 'car',
            'is_new' => 0,
            'price' => 12345,
            'registration_number' => 'FO25 FAZ',
            'vrm_condensed' => 'FO25FAZ',
            'cap_id' => 12311
        ]);

        $reservation = Reservation::factory()->create([
            'contact_number' => 1231231122,
            'email' => 'foo@faz.com',
            'vehicle_id' => $vehicle->id,
            'name' => 'Peter Parker',
        ]);

        $enquiry_action = Enquiries::makeAction('send-to-fuse');
        $enquiry_action->sendReservation($reservation);

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@faz.com'
            && $request['phone'] === 1231231122
            && $request['car_or_van'] === 'car'
            && $request['sale_type'] === 'Used'
            && $request['vehicle_interest'] === 'Audi'
            && $request['vehicle_model'] === 'A6'
            && $request['loan_amount'] == 12345
            && $request['vehicle_type'] === 'FO25FAZ'
            && $request['vehicle_cap_id'] === '12311'
            && stripos((string) $request['customer_comments'], 'Reservation') !== false
            && stripos((string) $request['customer_comments'], 'Payment reference') !== false);

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

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

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

        $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' => null],
            ],
            'source' => 'test.com',
        ]);

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

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

        Http::assertSent(fn (Request $request) => Str::contains($request->url(), 'https://foo.com/api/enquiry')
            && $request['forename'] === 'Peter'
            && $request['surname'] === 'Parker'
            && $request['email'] === 'foo@bar.com'
            && $request['phone'] === '00000111222'
            // ensure that null answer was converted to boolean false
            && $request['agreeMarketing'] === false);
    }

    public function testSyncReservationConfig()
    {
        $this->addFuseSettings();
        $this->addSyncReservationSettings();

        /** @var FuseCrmConfig $config */
        $config = App::make(FuseCrmConfig::class);
        $this->assertTrue($config->syncReservationEnabled());
        $this->assertEquals('https://reserve.foo.com', $config->syncReservationApiDomain());
        $this->assertEquals('test_reserve_api_key', $config->syncReservationApiKey());
    }

    public function testSyncReservedStatus()
    {
        $this->addFuseSettings();
        $this->addSyncReservationSettings();

        Http::fake([
            'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi' => Http::response(['success' => true], 200),
        ]);

        $make = VehicleMake::factory()->create(['name' => 'BMW']);
        $model = VehicleModel::factory()->create(['name' => 'X5']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'registration_number' => 'AB12 CDE',
            'vrm_condensed' => 'AB12CDE',
        ]);

        $reservation = Reservation::factory()->create([
            'vehicle_id' => $vehicle->id,
            'crm_reference' => 'PROP-TEST-1234',
            'name' => 'Test User',
            'email' => 'test@example.com',
        ]);

        $api = new FuseCrmApi(App::make(FuseCrmConfig::class));
        $result = $api->syncReservedStatus($reservation);

        $this->assertTrue($result);

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi')
                && $request->hasHeader('X-Fuse-Apikey', 'test_reserve_api_key')
                && $request['proposalId'] === 'PROP-TEST-1234'
                && $request['registration'] === 'AB12CDE'  // Spaces removed
                && $request['reserve'] === false
                && $request['voi'] === true;
        });

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi')
                && $request->hasHeader('X-Fuse-Apikey', 'test_reserve_api_key')
                && $request['proposalId'] === 'PROP-TEST-1234'
                && $request['registration'] === 'AB12CDE'  // Spaces removed
                && $request['reserve'] === true
                && $request['voi'] === false;
        });

        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm-voi')->get());
        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm-reserve')->get());

        $voiNotification = ApiNotification::query()->where('provider', 'fuse-crm-voi')->first();
        $this->assertEquals($reservation->id, $voiNotification->reference);
        $this->assertEquals($reservation->id, $voiNotification->data['reservation_id']);
        $this->assertEquals('PROP-TEST-1234', $voiNotification->data['proposal_id']);
        $this->assertNotNull($voiNotification->data['http_status']);

        $reserveNotification = ApiNotification::query()->where('provider', 'fuse-crm-reserve')->first();
        $this->assertEquals($reservation->id, $reserveNotification->reference);
        $this->assertEquals($reservation->id, $reserveNotification->data['reservation_id']);
        $this->assertEquals('PROP-TEST-1234', $reserveNotification->data['proposal_id']);
        $this->assertNotNull($reserveNotification->data['http_status']);
    }

    public function testSendReservationWithReserveEnabled()
    {
        $this->addFuseSettings();
        $this->addSyncReservationSettings();

        Http::fake([
            'https://foo.com/api/token' => Http::response(['access_token' => 'ABC123']),
            'https://foo.com/api/enquiry' => Http::response(['enquiryId' => 'PROP-TEST-5678'], 200),
            'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi' => Http::response(['success' => true], 200),
        ]);

        $make = VehicleMake::factory()->create(['name' => 'BMW']);
        $model = VehicleModel::factory()->create(['name' => 'X5']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'type' => 'car',
            'is_new' => 0,
            'price' => 45000,
            'registration_number' => 'AB12 CDE',
            'vrm_condensed' => 'AB12CDE',
            'cap_id' => 99999
        ]);

        $reservation = Reservation::factory()->create([
            'contact_number' => '07123456789',
            'email' => 'test@example.com',
            'vehicle_id' => $vehicle->id,
            'name' => 'John Doe',
        ]);

        $enquiry_action = Enquiries::makeAction('send-to-fuse');
        $result = $enquiry_action->sendReservation($reservation);

        $this->assertTrue($result);

        // Assert enquiry API was called
        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/api/enquiry')
                && $request['forename'] === 'John'
                && $request['surname'] === 'Doe';
        });

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi')
                && $request['proposalId'] === 'PROP-TEST-5678'
                && $request['registration'] === 'AB12CDE'  // Spaces removed
                && $request['reserve'] === false
                && $request['voi'] === true;
        });

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://reserve.foo.com/api/stock-list/vehicle/reserve-or-save-voi')
                && $request['proposalId'] === 'PROP-TEST-5678'
                && $request['registration'] === 'AB12CDE'  // Spaces removed
                && $request['reserve'] === true
                && $request['voi'] === false;
        });

        // Assert crm_reference was saved
        $reservation->refresh();
        $this->assertEquals('PROP-TEST-5678', $reservation->crm_reference);

        // Assert all API notifications were logged
        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm')->get());
        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm-voi')->get());
        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm-reserve')->get());

        // Verify tracking fields for VOI and Reserve notifications only
        $voiNotification = ApiNotification::query()->where('provider', 'fuse-crm-voi')->first();
        $this->assertEquals($reservation->id, $voiNotification->reference);
        $this->assertEquals($reservation->id, $voiNotification->data['reservation_id']);
        $this->assertEquals('PROP-TEST-5678', $voiNotification->data['proposal_id']);
        $this->assertNotNull($voiNotification->data['http_status']);

        $reserveNotification = ApiNotification::query()->where('provider', 'fuse-crm-reserve')->first();
        $this->assertEquals($reservation->id, $reserveNotification->reference);
        $this->assertEquals($reservation->id, $reserveNotification->data['reservation_id']);
        $this->assertEquals('PROP-TEST-5678', $reserveNotification->data['proposal_id']);
        $this->assertNotNull($reserveNotification->data['http_status']);
    }

    public function testSendReservationWithReserveDisabled()
    {
        $this->addFuseSettings();

        Http::fake([
            'https://foo.com/api/token' => Http::response(['access_token' => 'ABC123']),
            'https://foo.com/api/enquiry' => Http::response(['enquiryId' => 'PROP-TEST-9999'], 200),
        ]);

        $make = VehicleMake::factory()->create(['name' => 'Mercedes']);
        $model = VehicleModel::factory()->create(['name' => 'C-Class']);
        $vehicle = Vehicle::factory()->create([
            'make_id' => $make->id,
            'model_id' => $model->id,
            'type' => 'car',
            'is_new' => 1,
            'price' => 55000,
            'registration_number' => 'XY99 ZZZ',
            'vrm_condensed' => 'XY99ZZZ',
            'cap_id' => 88888
        ]);

        $reservation = Reservation::factory()->create([
            'contact_number' => '07987654321',
            'email' => 'jane@example.com',
            'vehicle_id' => $vehicle->id,
            'name' => 'Jane Smith',
        ]);

        $enquiry_action = Enquiries::makeAction('send-to-fuse');
        $result = $enquiry_action->sendReservation($reservation);

        $this->assertTrue($result);

        // Assert enquiry API was called
        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://foo.com/api/enquiry')
                && $request['forename'] === 'Jane'
                && $request['surname'] === 'Smith';
        });

        // Assert reserve API was NOT called
        Http::assertNotSent(function (Request $request) {
            return Str::contains($request->url(), 'reserve-or-save-voi');
        });

        // Assert crm_reference was saved
        $reservation->refresh();
        $this->assertEquals('PROP-TEST-9999', $reservation->crm_reference);

        // Assert only enquiry notification was logged (no VOI or reserve notifications)
        $this->assertCount(1, ApiNotification::query()->where('provider', 'fuse-crm')->get());
        $this->assertCount(0, ApiNotification::query()->where('provider', 'fuse-crm-voi')->get());
        $this->assertCount(0, ApiNotification::query()->where('provider', 'fuse-crm-reserve')->get());
    }

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

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

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client ID',
            'config_key' => 'fuse-crm-client-id',
            'type' => 'string',
            'value' => 'foo_client_id',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client Secret',
            'config_key' => 'fuse-crm-client-secret',
            'type' => 'secret',
            'value' => 'foo_client_secret',
        ]);

        Http::fake([
            '*/token' => Http::response([
                'access_token' => 'ABC123'
            ]),
            '*' => Http::response(null, 400),
        ]);
    }

    private function addSyncReservationSettings()
    {
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Sync Reservation Enabled',
            'config_key' => 'fuse-crm-sync-reservation-enabled',
            'type' => 'boolean',
            'value' => true,
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Sync Reservation API Key',
            'config_key' => 'fuse-crm-sync-reservation-api-key',
            'type' => 'secret',
            'value' => 'test_reserve_api_key',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Sync Reservation API Domain',
            'config_key' => 'fuse-crm-sync-reservation-domain',
            'type' => 'string',
            'value' => 'https://reserve.foo.com',
        ]);
    }

    private function addFuseSettings()
    {
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Enabled',
            'config_key' => 'fuse-crm-enabled',
            'type' => 'boolean',
            'value' => false,
        ]);

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

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client ID',
            'config_key' => 'fuse-crm-client-id',
            'type' => 'string',
            'value' => 'foo_client_id',
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Fuse',
            'name' => 'Client Secret',
            'config_key' => 'fuse-crm-client-secret',
            'type' => 'secret',
            'value' => 'foo_client_secret',
        ]);
    }
}
