<?php

namespace App\ExportMaps;

use App\ExportMaps\Contracts\ExportMapType;
use App\Facades\Settings;
use App\IntegrationRepository;
use App\Traits\ExportMapImageColumns;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleAttribute;

class VehicleExportMap implements ExportMapType
{
    use ExportMapImageColumns;

    public const NON_QUERYABLE_FIELDS = [
        'features.name',
        'specs.description',
        'equipment.description',
        'standardEquipment.description',
        'optionalEquipment.description',
        'custom1',
        'custom2',
        'custom3',
        'custom4',
        'custom5',
        'custom6',
        'site_url',
        'site_identifier',
        'colourMap.colour.colour',
        'dealership.lat',
        'dealership.lng',
        'empty',
    ];
    /**
     * Report name
     *
     * @return string
     */
    public function name(): string
    {
        return 'Vehicles';
    }

    /**
     * Columns that can be used
     *
     * @return string[]
     */
    public function columns(bool $onlyEnabledIntegrations = false): array
    {
        return array_merge(
            $this->getDefaultDataFields(),
            $this->getDealershipAdditionalDataFields($onlyEnabledIntegrations),
            $this->getSettingsBasedDataFields(),
            $this->getAttributeDataFields()
        );
    }

    public function queryableColumns(bool $onlyEnabledIntegrations = false): array
    {
        return array_filter(
            array_diff_key(
                $this->columns($onlyEnabledIntegrations),
                array_flip(array_merge(self::NON_QUERYABLE_FIELDS, $this->getImageNonQueryableFields()))
            ),
            fn ($value, $key) => !str_starts_with($key, 'dealership.data.')
                && !str_starts_with($key, 'attribute.'),
            ARRAY_FILTER_USE_BOTH
        );
    }

    /**
     * Start a query
     *
     * @return Builder
     */
    public function query(): Builder
    {
        return Vehicle::query();
    }

    private function getDefaultDataFields(): array
    {
        return [
            'uuid' => 'Unique Identifier',
            'registration_number' => 'Registration number',
            'vin' => 'VIN',
            'is_published' => 'Is Published',
            'is_sold' => 'Is Sold',
            'is_new' => 'Is New',
            'is_demo' => 'Is Demo',
            'is_reserved' => 'Is Reserved',
            'type' => 'Type (Car/LCV)',
            'title' => 'Title',
            'derivative' => 'Derivative',
            'make.name' => 'Vehicle make',
            'model.name' => 'Vehicle model',
            'fuelType.name' => 'Fuel Type',
            'drivetrain_id' => 'Drivetrain',
            'transmission.name' => 'Transmission',
            'dealership_id' => 'Dealership ID',
            'dealership.name' => 'Dealership Name',
            'dealership.address1' => 'Dealership Address 1',
            'dealership.county' => 'Dealership County',
            'dealership.postcode' => 'Dealership Postcode',
            'dealership.email' => 'Dealership Email',
            'bodyStyle.name' => 'Body Style',
            'price' => 'Price',
            'price_as_integer' => 'Price - without decimals',
            'monthly_price' => 'Monthly Price',
            'deposit' => 'Deposit',
            'colour' => 'Colour',
            'odometer_mi' => 'Odometer (miles)',
            'odometer_km' => 'Odometer (km)',
            'engine_size_cc' => 'Engine size (cc)',
            'co2' => 'CO2',
            'mpg' => 'MPG',
            'door_count' => 'Door count',
            'seats' => 'Seat count',
            'manufacture_year' => 'Manufacture year',
            'previous_owner_count' => 'Previous owner count',
            'image_count' => 'Image Count',
            'finance_examples_count' => 'Finance Examples Count',
            ...$this->getImageColumns(),
            'features.name' => 'Features',
            'specs.description' => 'Specs',
            'equipment.description' => 'Equipment - All',
            'standardEquipment.description' => 'Equipment - Standard',
            'optionalEquipment.description' => 'Equipment - Optional',
            'main_video_url' => 'Video URL',
            'cap_id' => 'CAP ID',
            'cap_code' => 'CAP Code',
            'auto_trader_id' => 'AutoTrader ID',
            'first_registration_date' => 'First registration date',
            'description' => 'Description text',
            'trim' => 'Trim',
            'attention_grabber' => 'Attention grabber text',
            'vehicle_length' => 'Vehicle length (mm)',
            'exterior_video_url' => 'Exterior video URL',
            'interior_video_url' => 'Interior video URL',
            'battery_range' => '[EV] Battery range',
            'battery_capacity_kwh' => '[EV] Battery capacity (kWh)',
            'battery_usable_capacity_kwh' => '[EV] Battery usable capacity (kWh)',
            'battery_charge_time' => '[EV] Battery charge time',
            'battery_quick_charge_time' => '[EV] Battery quick charge time',
            'battery_quick_charge_level' => '[EV] Battery level at end of quick charge',
            'wheelbase_type' => 'Wheelbase (mm)',
            'wheelbase_mm' => 'Wheelbase (mm)',
            'payload_kg' => 'Payload (kg)',
            'gross_vehicle_weight_kg' => 'Gross vehicle weight (kg)',
            'bhp' => 'BHP',
            'empty' => 'Empty value',
            'site_identifier' => 'Site Identifier',
            'reservation_amount' => 'Reservation Amount',
            'vrm_condensed' => 'VRM Condensed',
            'condition' => 'Condition',
            'created_at' => 'Created at',
            'updated_at' => 'Updated at',
            'rrp_price' => 'RRP price',
            'is_vat_applicable' => 'Is VAT applicable',
            'available_date' => 'Available from date',
            'custom1' => '[Custom] - Mapping Rules Field 1',
            'custom2' => '[Custom] - Mapping Rules Field 2',
            'custom3' => '[Custom] - Mapping Rules Field 3',
            'custom4' => '[Custom] - Mapping Rules Field 4',
            'custom5' => '[Custom] - Mapping Rules Field 5',
            'custom6' => '[Custom] - Mapping Rules Field 6',
            'colourMap.colour.colour' => 'Colour from Colour Map',
            'days_since_first_registration' => 'Days since first registration date',
            'calculated_available_date' => 'Available from date - calculated for empty',
            'site_url' => 'Site URL',
            'stock_provider' => 'Stock Provider',
            'admin_fee' => 'Admin Fee',
            'original_price' => 'Original Price',
            'previous_price' => 'Previous Price',
            'monthly_cost_type' => 'Monthly Cost Type',
            'personalized_number_plate' => 'Personalized Number Plate',
            'featured' => 'Is Featured',
            'stock_arrival_date' => 'Stock Arrival Date',
            'plug_type' => '[EV] Plug Type',
            'rapid_charge_plug_type' => '[EV] Rapid Charge Plug Type',
            'battery_quick_charge_start_level' => '[EV] Battery Quick Charge Start Level',
            'battery_slow_charge_description' => '[EV] Battery Slow Charge Description',
            'battery_quick_charge_description' => '[EV] Battery Quick Charge Description',
            'drivetrain.name' => 'Drivetrain',
            'dealership.address2' => 'Dealership Address 2',
            'dealership.city' => 'Dealership City',
            'dealership.contact_no' => 'Dealership Phone',
            'dealership.country' => 'Dealership Country',
            'dealership.lat' => 'Dealership Latitude',
            'dealership.lng' => 'Dealership Longitude',
        ];
    }

    protected function getDealershipAdditionalDataFields(bool $onlyEnabledIntegrations = true): array
    {
        $integrationRepository = App::make(IntegrationRepository::class);
        $integrations = $onlyEnabledIntegrations ?
            $integrationRepository->getEnabledForType('sales-channels') :
            $integrationRepository->getAllForType('sales-channels');

        return $integrations
            ->filter(fn($integration) => !empty($integration['class'])
                && class_exists($integration['class'])
                && method_exists($integration['class'], 'dealershipAdditionalDataFields'))
            ->flatMap(function ($integration) {
                $instance = App::make($integration['class']);
                $fields = $instance->dealershipAdditionalDataFields();
                return collect($fields)->mapWithKeys(fn($fieldData, $fieldKey) => [
                    'dealership.data.' . $fieldKey => '[Dealership] ' . ($fieldData['label'] ?? $fieldKey),
                ]);
            })
            ->all();
    }

    private function getAttributeDataFields(): array
    {
        return VehicleAttribute::query()
            ->where('model', (new Vehicle())->getMorphClass())
            ->orderBy('name')
            ->get()
            ->mapWithKeys(fn (VehicleAttribute $attribute) => [
                'attribute.' . $attribute->slug => $attribute->name,
            ])
            ->all();
    }

    private function getSettingsBasedDataFields(): array
    {
        return collect([
            [
                'field' => 'is_pre_reg',
                'name' => 'Is Pre-Reg',
                'enabled' => Settings::get('vehicles-pre-reg-condition-enabled'),
            ],
        ])
            ->filter(fn ($dataField) => $dataField['enabled'] ?? true)
            ->pluck('name', 'field')
            ->toArray();
    }
}
