<?php

namespace App\Http\Resources\VehicleAction;

use App\Facades\Settings;
use App\IntegrationRepository;
use App\Sales\SilverBullet;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Vehicle;

class FinanceFactory
{
    public function get(Vehicle $vehicle)
    {
        if ($this->hasKeyloopFinance()) {
            return App::make(SilverBullet::class)->getVehicleAction($vehicle, 'finance');
        }
        return false;
    }

    public function widget(Vehicle $vehicle)
    {
        return match ($this->enabledFinanceProvider()) {
            'keyloop' => $this->keyloopWidget(),
            'ivendi' => $this->ivendiWidget($vehicle),
            'code-weavers' => $this->codeWeaversWidget($vehicle),
            'evolution-funding' => $this->evolutionWidget($vehicle),
            'santander' => $this->santanderWidget($vehicle),
            default => $this->defaultCalculator($vehicle),
        };
    }

    private function hasKeyloopFinance(): bool
    {
        return Settings::get('sales-silver-bullet-enabled')
            && Settings::get('sales-silver-bullet-finance');
    }

    private function keyloopWidget()
    {
        return null;
    }

    private function ivendiWidget(Vehicle $vehicle)
    {
        if (empty($vehicle->price)) {
            return null;
        }

        return [
            'type' => 'component',
            'value' => 'IVendiCalculator',
            'data' => [
                'change_values' => Settings::get('finance-front-end-calculator-enabled') === true,
                'username' => Settings::get('finance-ivendi-api_key'),
                'quotee_uid' => $vehicle->dealership?->data['ivendi'] ?? null,
                'class' => $this->ivendiVehicleType($vehicle->type),
                'condition' => $vehicle->is_new ? 'new' : 'used',
                'registration_number' => $vehicle->vrm_condensed ?? 'New Vehicle',
                'first_registration_date' => $vehicle->first_registration_date?->format('d/m/Y'),
                'cap_code' => $vehicle->cap_code,
                'cap_id' => $vehicle->cap_id,
                'price' => (int)$vehicle->price,
                'vat_included' => $vehicle->type !== 'lcv',
                'vat_qualifying' => true,
                'mileage' => $vehicle->odometer_mi ?? 0,
                'image' => $vehicle->getPreviewImage('large'),
                'make' => $vehicle->make->name ?? '',
                'model' => $vehicle->model->name ?? '',
                'derivative' => $vehicle->derivative ?? '',
                'fuel_type' => $vehicle->fuelType->name ?? '',
                'deposit' => Settings::get('finance-deposit_percentage'),
                'term' => Settings::get('finance-term'),
                'annual_mileage' => Settings::get('finance-annual_mileage'),
                'credit_rating' => Settings::get('finance-credit_rating'),
            ],
        ];
    }

    private function codeWeaversWidget(Vehicle $vehicle)
    {
        if (
            empty($vehicle->first_registration_date)
            && Settings::get('sales-codeweavers-widget-enabled-for-new-vehicles') !== true
        ) {
            return null;
        }

        return [
            'type' => 'component',
            'value' => 'CodeweaversCalculator',
            'data' => [
                'change_values' => $this->getCodeweaversWidgetChangeValues($vehicle),
                'key' => Settings::get('finance-codeweavers-api_key'),
                'type' => $vehicle->type,
                'is_new' => $vehicle->is_new,
                'registration_number' => $vehicle->registration_number,
                'first_registration_date' => $vehicle->first_registration_date?->format('Y-m-d'),
                'cap_id' => $vehicle->cap_id,
                'identifier' => $this->getIdentifier($vehicle),
                'price' => $vehicle->price,
                'mileage' => $vehicle->odometer_mi,
                'image' => $vehicle->getPreviewImage('large'),
                'deposit' => round(Settings::get('finance-deposit_percentage') * 0.01 * $vehicle->price),
                'term' => Settings::get('finance-term'),
                'annual_mileage' => Settings::get('finance-annual_mileage'),
                'credit_rating' => Settings::get('finance-credit_rating'),
                'dealer_id' => $vehicle->dealership->data['codeweavers']
                    ?? Settings::get('finance-codeweavers-dealer_name'),
                'apply_url' => 'https://services.codeweavers.net/forms/quote/{quote}/apply'
            ],
        ];
    }

    private function santanderWidget(Vehicle $vehicle)
    {
        if (empty($vehicle->cap_code)) {
            return null;
        }

        return [
            'type' => 'component',
            'value' => 'FinanceCalculator',
            'data' => [
                'change_values' => Settings::get('finance-front-end-calculator-enabled') === true,
                'type' => $vehicle->type,
                'is_new' => $vehicle->is_new,
                'registration_number' => $vehicle->registration_number,
                'first_registration_date' => $vehicle->first_registration_date?->format('Y-m-d'),
                'cap_id' => $vehicle->cap_id,
                'cap_code' => $vehicle->cap_code,
                'price' => $vehicle->price,
                'mileage' => $vehicle->odometer_mi,
                'image' => $vehicle->getPreviewImage('large'),
                'deposit' => round(Settings::get('finance-deposit_percentage') * 0.01 * $vehicle->price),
                'term' => Settings::get('finance-term'),
                'annual_mileage' => Settings::get('finance-annual_mileage'),
                'credit_rating' => Settings::get('finance-credit_rating'),
                'dealer_id' => Settings::get('finance-santander-dealer-code'),
            ],
        ];
    }

    private function getCodeweaversWidgetChangeValues(Vehicle $vehicle)
    {
        $vehicle_is_eligible = false;

        if ($vehicle->is_new) {
            if (Settings::get('sales-codeweavers-widget-enabled-for-new-vehicles') === true) {
                $vehicle_is_eligible = true;
            }
        } else {
            // used vehicles are eligible for finance calculator
            $vehicle_is_eligible = true;
        }

        return $vehicle_is_eligible && Settings::get('finance-front-end-calculator-enabled') === true;
    }

    private function evolutionWidget(Vehicle $vehicle)
    {
        return [
            'type' => 'component',
            'value' => 'EvolutionCalculator',
            'data' => [
                'change_values' => Settings::get('finance-front-end-calculator-enabled') === true,
                'key' => Settings::get('finance-evolution-client_id'),
                'type' => $vehicle->type,
                'is_new' => $vehicle->is_new,
                'make' => $vehicle->make->name,
                'model' => $vehicle->model->name,
                'derivative' => $vehicle->derivative,
                'registration_number' => $vehicle->registration_number,
                'first_registration_date' => $vehicle->first_registration_date,
                'vat_applicable' => $vehicle->type !== 'lcv',
                'cap_id' => $vehicle->cap_id,
                'price' => $vehicle->price,
                'mileage' => $vehicle->odometer_mi,
                'image' => $vehicle->getPreviewImage('large'),
                'deposit' => Settings::get('finance-deposit_percentage'),
                'term' => Settings::get('finance-term'),
                'annual_mileage' => Settings::get('finance-annual_mileage'),
                'credit_rating' => Settings::get('finance-credit_rating'),
            ],
        ];
    }

    private function enabledFinanceProvider()
    {
        return new IntegrationRepository()->getEnabledForType('finance')
            ->keys()
            ->first();
    }

    private function defaultCalculator(Vehicle $vehicle)
    {
        return [
            'type' => 'component',
            'value' => 'FinanceCalculator',
            'data' => [
                'change_values' => Settings::get('finance-front-end-calculator-enabled') === true,
                'values' => $this->mapValues($vehicle->financeExamples()
                    ->orderBy('monthly_price')
                    ->first()),
            ]
        ];
    }

    private function mapValues(?Model $example)
    {
        if (!$example) {
            return null;
        }

        return collect($example->getFillable())
            ->reject(fn($field) => in_array($field, ['vehicle_id', 'provider']))
            ->map(fn($field) => [
                'id' => $field,
                'is_price' => in_array($field, ['deposit', 'first_payment', 'final_payment', 'monthly_price']),
                'name' => __('labels.finance.' . $field),
                'value' => $this->formatValue($field, $example[$field]),
            ])
            ->toArray();
    }

    private function formatValue($field, mixed $value)
    {
        if (in_array($field, ['finance_type', 'apply_url', 'terms_and_conditions'])) {
            return $value;
        }

        if (in_array($field, ['apr', 'interest_rate'])) {
            return round($value, 1) . '%';
        }

        return round($value, 0);
    }

    private function getIdentifier(Vehicle $vehicle): array
    {
        if (!empty($vehicle->cap_id)) {
            return [
                "type" => "CAPSHORTCODE",
                "value" => $vehicle->cap_id
            ];
        }

        return [
            "type" => "VRM",
            "value" => $vehicle->registration_number,
        ];
    }

    private function ivendiVehicleType(?string $type): string
    {
        // iVendi want caravans as motorhomes
        if ($type === 'caravan') {
            return 'motorhome';
        }

        return $type;
    }
}
