<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use Database\Seeders\Tenant\FinanceSettingSeeder;
use Illuminate\Support\Facades\Bus;
use Mtc\MercuryDataModels\Finance\Contracts\FinanceResultCollection;
use Mtc\MercuryDataModels\Finance\Jobs\FetchVehicleFinanceData;
use Mtc\MercuryDataModels\Services\FinanceService;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TenantTestCase;

class FinanceServiceTest extends TenantTestCase
{
    public function testPercentageDeposit()
    {
        Bus::fake();

        $this->seed(FinanceSettingSeeder::class);
        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-deposit_percentage', 10);

        $vehicle = Vehicle::factory()->create([
            'price' => 1000,
        ]);

        $data = [
            'term' => 60,
            //'deposit' => 100,
            'annual_mileage' => 8000,
            'credit_rating' => '',
        ];

        new FinanceService()->request($vehicle, $data);

        // assert that the deposit is calculated as a percentage of the vehicle price
        Bus::assertDispatched(fn (FetchVehicleFinanceData $job) => $job->deposit == 100);
    }

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

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

        Settings::make([
            'tab' => 'Automotive',
            'section' => 'Finance',
            'group' => 'General',
            'name' => 'Minimum default deposit amount',
            'config_key' => 'finance-minimum-deposit-amount',
            'type' => 'int',
            'value' => 999,
        ]);

        Settings::update('finance-codeweavers-enabled', true);
        Settings::update('finance-codeweavers-api_key', 'foo-baz-bar');
        Settings::update('finance-codeweavers-username', 'lorem');
        Settings::update('finance-codeweavers-password', 'ipsum');
        Settings::update('finance-deposit_percentage', 10);

        $vehicle = Vehicle::factory()->create([
            'price' => 1000,
        ]);

        $data = [
            'term' => 60,
            //'deposit' => 100,
            'annual_mileage' => 8000,
            'credit_rating' => '',
        ];

        new FinanceService()->request($vehicle, $data);

        // assert that the percentage deposit is overwritten by the minimum deposit
        Bus::assertDispatched(fn (FetchVehicleFinanceData $job) => $job->deposit == 999);
    }

    public function testHandleReturnsEmptyCollectionWhenVehicleHasNoPrice()
    {
        $vehicle = Vehicle::factory()->create([
            'price' => null,
        ]);

        // A null price would previously fatal building the FinanceRequestData; the guard
        // should short-circuit and return an empty result collection without fetching.
        $result = new FetchVehicleFinanceData($vehicle, 60, 8000, 0, '', [], false)->handle();

        $this->assertInstanceOf(FinanceResultCollection::class, $result);
        $this->assertTrue($result->isEmpty());
    }

    public function testHandleReturnsEmptyCollectionWhenVehiclePriceIsOnApplication()
    {
        // The Vehicle "no price" scopes treat price <= 1 as price on application.
        $vehicle = Vehicle::factory()->create([
            'price' => 1,
        ]);

        $result = new FetchVehicleFinanceData($vehicle, 60, 8000, 0, '', [], false)->handle();

        $this->assertInstanceOf(FinanceResultCollection::class, $result);
        $this->assertTrue($result->isEmpty());
    }
}
