<?php

namespace Tests\Feature;

use App\Crm\Config\DealerWebConfig;
use App\Facades\Settings;
use App\Jobs\ProcessIncomingReservationJob;
use App\Services\DealershipDetection;
use App\Services\DealerWebLmsApi;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\VehicleReservations\Console\Commands\IngestReservations;
use Mtc\VehicleReservations\Reservation;
use Tests\TestCase;
use Tests\UserForTenant;

class VehicleReservationTest extends TestCase
{
    use DatabaseMigrations;
    use UserForTenant;

    protected $tenancy = true;

    public function testReservationIngest()
    {
        Bus::fake();

        Reservation::factory()->create([
            'ingested_at' => null,
            'confirmed_at' => Carbon::now()->subMinutes(10),
        ]);

        $command = $this->artisan(IngestReservations::class);
        $command->run();

        Bus::assertDispatched(ProcessIncomingReservationJob::class);
        Bus::assertNotDispatched(\Mtc\VehicleReservations\Jobs\ProcessIncomingReservationJob::class);
    }

    public function testDealerWebReservationData()
    {
        $debug_endpoint = 'dealerweb-debug-endpoint';

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Dealer Web LMS',
            'name' => 'Dealer Web Endpoint',
            'config_key' => 'dealerweblms-endpoint',
            'type' => 'string',
            'value' => $debug_endpoint,
            'description' => 'Dealer Web LMS endpoint',
        ]);

        Http::fake([
            $debug_endpoint => Http::response('<AddLeadResult>
                <CustomerID>123456</CustomerID>
                <ErrorCode>0</ErrorCode>
                <ErrorMessage />
            </AddLeadResult>
            '),
            "*" => Http::response([], 400),
        ]);

        $vehicle = Vehicle::factory()->create([
            'is_new' => true,
            'registration_number' => 'ABC123',
        ]);

        $reservation = Reservation::factory()->create([
            'vehicle_id' => $vehicle->id,
            'amount' => 99,
            'ingested_at' => null,
            'confirmed_at' => Carbon::now()->subMinutes(10),
        ]);

        (new DealerWebLmsApi(new DealerWebConfig(), new DealershipDetection()))->sendReservation($reservation);

        Http::assertSent(function (Request $request) {
            return Str::contains($request->body(), 'Amount Paid: 99')
                && Str::contains($request->body(), 'Vehicle Registration: ABC123');
        });
    }

    public function testProcessJobCallsDealerweb()
    {
        $debug_endpoint = 'dealerweb-debug-endpoint';

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Dealer Web LMS',
            'name' => 'Dealer Web Endpoint',
            'config_key' => 'dealerweblms-endpoint',
            'type' => 'string',
            'value' => $debug_endpoint,
        ]);

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'Dealer Web LMS',
            'name' => 'Dealer Web Endpoint',
            'config_key' => 'dealerweblms-send-reservations',
            'type' => 'boolean',
            'value' => true,
        ]);

        Http::fake([
            $debug_endpoint => Http::response('<AddLeadResult>
                <CustomerID>123456</CustomerID>
                <ErrorCode>0</ErrorCode>
                <ErrorMessage />
            </AddLeadResult>
            '),
            "*" => Http::response([], 400),
        ]);

        $vehicle = Vehicle::factory()->create([
            'is_new' => true,
            'registration_number' => 'ABC123',
        ]);

        $reservation = Reservation::factory()->create([
            'vehicle_id' => $vehicle->id,
            'amount' => 99,
            'status' => 'confirmed',
            'ingested_at' => null,
            'confirmed_at' => Carbon::now()->subMinutes(10),
        ]);

        (new ProcessIncomingReservationJob($reservation))->handle();

        Http::assertSent(function (Request $request) use ($debug_endpoint) {
            return Str::contains($request->url(), $debug_endpoint);
        });
    }

    public function testProcessJobCallsEnquiryMax()
    {
        Config::set('services.enquiry-max.mode', 'live');

        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'enquiry max',
            'name' => 'enquiry max',
            'config_key' => 'crm-enquiry-max-send-reservations',
            'type' => 'boolean',
            'value' => true,
        ]);
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'enquiry max',
            'name' => 'enquiry max',
            'config_key' => 'crm-enquiry-max-enabled',
            'type' => 'boolean',
            'value' => true,
        ]);
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'enquiry max',
            'name' => 'enquiry max',
            'config_key' => 'crm-enquiry-max-client-id',
            'type' => 'string',
            'value' => '123',
        ]);
        Settings::make([
            'tab' => 'CRM',
            'section' => 'Integrations',
            'group' => 'enquiry max',
            'name' => 'enquiry max',
            'config_key' => 'crm-enquiry-max-client-secret',
            'type' => 'string',
            'value' => '456',
        ]);

        Http::fake([
            'https://api.enquirymax.net/*' => Http::response([
                'accessToken' => 'foo',
            ]),
            "*" => Http::response([], 400),
        ]);

        $vehicle = Vehicle::factory()->create([
            'is_new' => true,
            'registration_number' => 'ABC123',
        ]);

        $reservation = Reservation::factory()->create([
            'vehicle_id' => $vehicle->id,
            'amount' => 99,
            'status' => 'confirmed',
            'ingested_at' => null,
            'confirmed_at' => Carbon::now()->subMinutes(10),
        ]);

        (new ProcessIncomingReservationJob($reservation))->handle();

        Http::assertSent(function (Request $request) {
            return Str::contains($request->url(), 'https://api.enquirymax.net');
        });
    }
}
