<?php

namespace App\Imports;

use App\Facades\Settings;
use App\Jobs\CreateAIVehicleDescriptions;
use App\Jobs\ImportImagesFromUrlList;
use App\Master\Models\VehicleMake;
use App\Master\Models\VehicleModel;
use App\Models\ImportMap;
use App\Models\ImportMapField;
use App\TaxonomyMap;
use App\Traits\MapsTaxonomies;
use App\VehicleSpec\Jobs\FetchVehicleListSpecData;
use App\VehicleType;
use Carbon\Carbon;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Mtc\ContentManager\Facades\Media;
use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\Country;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\DrivetrainType;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\TransmissionType;
use Mtc\MercuryDataModels\Vehicle;

class VehicleImport implements ToCollection, WithHeadingRow
{
    use DispatchesJobs;
    use MapsTaxonomies;
    use Traits\VehicleImportFlow;

    protected static array $vehicleFillable = [];

    private ?ImportMap $importMap;

    private string $dealershipMatchValue = 'location_stock';

    private array $additional_tasks = [];

    public function __construct(
        private readonly ?string $importType = '',
        private ?Collection $dealerships = null,
        private ?Collection $makes = null,
        private ?Collection $models = null,
        private ?Collection $fuel_types = null,
        private ?Collection $body_styles = null,
        private ?Collection $drivetrains = null,
        private ?Collection $transmissions = null
    ) {
        $this->loadRelationships();
    }

    public function setAdditionalTasks(array $tasks): self
    {
        $this->additional_tasks = $tasks;
        return $this;
    }

    public function setImportMap(ImportMap $importMap): self
    {
        $this->importMap = $importMap;
        return $this;
    }

    public function model(array $source)
    {
        $row = match ($this->importType) {
            'net-director' => $this->mapNetDirectorData($source),
            '' => $source,
            default => $this->mapBasedOnImportMap($source)
        };

        $model = $this->processRow($row);
        $this->storeUnmappedTaxonomy($model);
        return $model;
    }

    private function mapNetDirectorData($row): array
    {
        $country = Settings::get('app-details-country') ?? config('app.default_country');
        $registration_number = Country::normalizeNumberPlate(
            $country,
            $row['vrm'],
            false
        );

        $make_id = $this->getMappedTaxonomy(TaxonomyMap::MAKE, $row['manufacturer'], $row);
        $make_name = VehicleMake::find($make_id)?->name;

        $model_id = $this->getMappedTaxonomy(TaxonomyMap::MODEL, $row['model'], $row);
        $model_name = VehicleModel::find($model_id)?->name;

        return [
            'uuid' => $row['identifiers_ndstock_uuid'],
            'stock_provider' => 'net-director-import',
            'description' => $row['clientdata_description'],
            'is_new' => $row['clientdata_new'],
            'type' => match ($row['vehicle_type']) {
                'Car' => VehicleType::CAR->value,
                'LCV' => VehicleType::LCV->value,
                'Motorcycle' => VehicleType::MOTORCYCLE->value,
            },
            'registration_number' => $registration_number,
            'vin' => $row['vin'],
            'colour' => $row['colour'],
            'derivative' => $row['descriptive_variant'],
            'transmission_id' => $this->getMappedTaxonomy(TaxonomyMap::TRANSMISSION, $row['transmission_type'], $row),
            'price' => $row['price'],
            'original_price' => $row['old_price'],
            'fuel_type_id' => $this->getMappedTaxonomy(TaxonomyMap::FUEL_TYPE, $row['fuel_type_name'], $row),
            'odometer_mi' => ($row['odometer_unit'] == 'km'
                ? (new Vehicle())->kmToMiles($row['odometer_reading'])
                : $row['odometer_reading']),
            'make_id' => $make_id,
            'model_id' => $model_id,
            'dealership_id' => $this->dealershipId($row['location_id']),
            'engine_size_cc' => $row['engine_size_cc'],
            'body_style_id' => $this->getMappedTaxonomy(TaxonomyMap::BODY_STYLE, $row['body_style_name'], $row),
            'cap_id' => $row['cap_id'],
            'bhp' => $row['bhp'],
            'attention_grabber' => $row['attention_grabber'],
            'featured' => $row['featured'],
            'mpg' => (int)$row['mpg'],
            'doors' => $row['doors'],
            'is_demo' => $row['ex_demo'],
            'co2' => (int)$row['co2'],
            'previous_owner_count' => $row['number_of_previous_owners'],
            'trim' => $row['interior_trim'],
            'first_registration_date' => Carbon::parse($row['registration_date']),
            'manufacture_year' => $row['registration_year'],
            'service_history' => $row['service_history'],
            'slug' => Str::slug(
                $registration_number . '-' . ($make_name ?? '') . '-' . ($model_name ?? '')
            ),
            'title' => $make_name . ' ' . $model_name,
            'images' => str_replace(',', '|', $row['image_urls']),
            'features' => str_replace([',', ';'], '|', $row['standard_equipment']),
            'door_count' => (int)$row['doors'],
            'main_video_url' => !empty($row['youtube_video_id'])
                ? 'https://www.youtube.com/embed/' . $row['youtube_video_id']
                : '',
            'is_sold' => strpos($row['sale_status'], 'Show as sold'),
            'is_published' => $row['sale_status'] == 'Live',
            'is_reserved' => strpos($row['sale_status'], 'Deposit'),
        ];
    }

    protected function getDetailsForTaxonomyMap(array $record): array
    {
        return $record;
    }

    public function collection(Collection $collection): void
    {
        $this->triggerAdditionalTasks(
            $collection->map(fn(Collection $row) => $this->model($row->toArray()))->filter()
        );
    }

    private function triggerAdditionalTasks(Collection $vehicles): void
    {
        foreach ($this->additional_tasks as $task) {
            match ($task) {
                'vehicle-specs' => FetchVehicleListSpecData::dispatch($vehicles),
                'ai-content' => CreateAIVehicleDescriptions::dispatch(false, $vehicles),
                default => null,
            };
        }
    }
}
