<?php

namespace Tests\Unit\Crm;

use App\Crm\SendToDealerWebLms;
use App\Services\DealerWebLmsApi;
use Mockery;
use Mtc\MercuryDataModels\Booking;
use Mtc\VehicleReservations\Reservation;
use PHPUnit\Framework\TestCase;

class SendToDealerWebLmsTest extends TestCase
{
    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public function testFormAdditionalDataFieldsExposesLeadTypeOverride(): void
    {
        $subject = new SendToDealerWebLms(Mockery::mock(DealerWebLmsApi::class));

        $fields = $subject->formAdditionalDataFields();

        $this->assertArrayHasKey('lead-type', $fields);
        $this->assertSame('text', $fields['lead-type']['type']);
        $this->assertStringContainsString('LeadType', $fields['lead-type']['label']);
    }

    public function testDealershipAdditionalDataFieldsIncludeDealerIdAndUsername(): void
    {
        $subject = new SendToDealerWebLms(Mockery::mock(DealerWebLmsApi::class));

        $fields = $subject->dealershipAdditionalDataFields();

        $this->assertArrayHasKey('dealerweb-dealer-id', $fields);
        $this->assertArrayHasKey('dealerweb-username', $fields);
        $this->assertSame('text', $fields['dealerweb-dealer-id']['type']);
        $this->assertSame('text', $fields['dealerweb-username']['type']);
    }

    public function testFormQuestionDataFieldsAdvertiseMappableLmsFields(): void
    {
        $subject = new SendToDealerWebLms(Mockery::mock(DealerWebLmsApi::class));

        $fields = $subject->formQuestionDataFields();

        $this->assertArrayHasKey('dealer-web-lms-field', $fields);
        $this->assertSame('select', $fields['dealer-web-lms-field']['type']);

        $choices = $fields['dealer-web-lms-field']['choices'];
        $this->assertArrayHasKey('DealerNo', $choices);
        $this->assertArrayHasKey('Forename', $choices);
        $this->assertArrayHasKey('Surname', $choices);
        $this->assertArrayHasKey('Email', $choices);
        $this->assertArrayHasKey('Tel_Mobile', $choices);
        $this->assertArrayHasKey('PexRegNo', $choices);
        $this->assertArrayHasKey('URL', $choices);
    }

    public function testFailureReasonReturnsApiMessageWhenPresent(): void
    {
        $api = Mockery::mock(DealerWebLmsApi::class);
        $api->shouldReceive('getResponseMessage')->once()->andReturn('Bad DealerNo');

        $subject = new SendToDealerWebLms($api);

        $this->assertSame('Bad DealerNo', $subject->failureReason());
    }

    public function testFailureReasonFallsBackToUnknownErrorWhenApiHasNoMessage(): void
    {
        $api = Mockery::mock(DealerWebLmsApi::class);
        $api->shouldReceive('getResponseMessage')->once()->andReturnNull();

        $subject = new SendToDealerWebLms($api);

        $this->assertSame('Unknown error', $subject->failureReason());
    }

    public function testSendServiceBookingDelegatesToApiAndReturnsResult(): void
    {
        $booking = Mockery::mock(Booking::class);
        $api = Mockery::mock(DealerWebLmsApi::class);
        $api->shouldReceive('sendServiceBooking')
            ->once()
            ->with($booking)
            ->andReturnTrue();

        $subject = new SendToDealerWebLms($api);

        $this->assertTrue($subject->sendServiceBooking($booking));
    }

    public function testSendReservationDelegatesToApiAndReturnsResult(): void
    {
        $reservation = Mockery::mock(Reservation::class);
        $api = Mockery::mock(DealerWebLmsApi::class);
        $api->shouldReceive('sendReservation')
            ->once()
            ->with($reservation)
            ->andReturnFalse();

        $subject = new SendToDealerWebLms($api);

        $this->assertFalse($subject->sendReservation($reservation));
    }
}
