<?php

namespace App\Http\Resources;

use App\Facades\Feature;
use App\Facades\Settings;
use App\IntegrationRepository;
use App\Models\ImportMap;
use App\Traits\FormatAsCurrency;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Vehicle;

class VehicleListResource extends JsonResource
{
    use FormatAsCurrency;

    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        $show_providers = tenant('type') !== 'listing'
            && Vehicle::query()->distinct()->pluck('stock_provider')->count() > 1;
        if ($this->resource instanceof LengthAwarePaginator) {
            $this->resource
                ->through(fn(Vehicle $vehicle) => $this->mapVehicle($vehicle, $show_providers));
        } else {
            $this->resource = $this->resource
                ->map(fn(Vehicle $vehicle) => $this->mapVehicle($vehicle, $show_providers));
            return parent::toArray($request);
        }

        $resource = $this->resource->toArray();
        $resource['soft_deletes'] = true;
        $resource['view_columns'] = $this->getViewColumns();
        $resource['default_columns'] = [
            'registration_number',
            'price',
        ];
        return $resource;
    }

    /**
     * Convert vehicle to the json format used in lists
     *
     * @param Vehicle $vehicle
     * @return array
     */
    protected function mapVehicle(Vehicle $vehicle, bool $show_providers = false)
    {
        return [
            'image' => [
                'src' => $this->getVehicleImageSrc($vehicle),
                'alt' => $vehicle->title,
            ],
            'active' => $vehicle->is_published,
            'status' => $vehicle->status,
            'title' => $vehicle->title,
            'deleted_at' => $vehicle->deleted_at,
            'description' => collect([
                $show_providers ? $this->formatStockProvider($vehicle->stock_provider) : null,
                $vehicle->derivative,
            ])->filter()->implode(' | '),
            'metaItems' => $this->getVehicleMetaItems($vehicle),
            'link' => '/manage-content/vehicles/edit/' . $vehicle->id,
            'uuid' => $vehicle->uuid,
            'id' => $vehicle->id,
            'featured' => (bool) $vehicle->featured,
        ];
    }

    private function getVehicleMetaItems(Vehicle $vehicle): array
    {
        return collect([
            [
                'name' => 'is_reserved',
                'value' => $vehicle->is_reserved ? 'Y' : 'N',
            ],
            [
                'name' => 'is_sold',
                'value' => $vehicle->is_sold ? 'Y' : 'N',
            ],
            [
                'name' => 'is_new',
                'value' => $vehicle->is_new ? 'Y' : 'N',
            ],
            [
                'name' => 'registration_number',
                'value' => $vehicle->registration_number,
            ],
            [
                'name' => 'mileage',
                'value' => $vehicle->odometer_mi,
            ],
            [
                'name' => 'price',
                'value' => $this->asCurrency($vehicle->price ?? 0.0, tenant()->currency),
            ],
            [
                'name' => 'search_views',
                'value' => $vehicle->search_views ?? 0,
            ],
            [
                'name' => 'views',
                'value' => $vehicle->view_count ?? 0,
            ],
            [
                'name' => 'image_count',
                'value' => $vehicle->image_count ?? 0,
            ],
            [
                'name' => 'enquiry_count',
                'value' => $vehicle->enquiry_count ?? 0,
            ],
            [
                'name' => 'days_in_stock',
                'value' => $vehicle->days_in_stock,
            ],
            [
                'name' => 'days_since_update',
                'value' => $vehicle->days_since_update,
            ],
            [
                'name' => 'has_description',
                'value' => !empty($vehicle->description) ? 'Not empty' : 'Empty',
            ],
            [
                'name' => 'has_attention_grabber',
                'value' => !empty($vehicle->attention_grabber) ? 'Not empty' : 'Empty',
            ],
            [
                'name' => 'at_publish_advert',
                'value' => $vehicle->autoTraderDataPublishAdvertStatus,
                'enabled' => Settings::get('sales-channels-auto-trader-enabled'),
            ]
        ])
            ->filter(fn($item) => $item['enabled'] ?? true)
            ->pluck('value', 'name')
            ->toArray();
    }

    private function getViewColumns(): array
    {
        return collect([
            [
                'id' => 'is_reserved',
                'name' => 'Reserved',
            ],
            [
                'id' => 'is_sold',
                'name' => 'Sold',
            ],
            [
                'id' => 'is_new',
                'name' => 'Is New',
            ],
            [
                'id' => 'registration_number',
                'name' => 'Registration Number',
                'icon' => 'cars',
            ],
            [
                'id' => 'mileage',
                'name' => 'Mileage',
                'icon' => 'gauge',
            ],
            [
                'id' => 'price',
                'name' => 'Price',
                'icon' => 'tag',
            ],
            [
                'id' => 'search_views',
                'name' => 'Search appearances',
                'icon' => 'magnifying-glass',
            ],
            [
                'id' => 'views',
                'name' => 'Ad views',
                'icon' => 'eye',
            ],
            [
                'id' => 'image_count',
                'name' => 'Image count',
                'icon' => 'images',
            ],
            [
                'id' => 'enquiry_count',
                'name' => 'Enquiry count',
                'icon' => 'envelope-dot',
            ],
            [
                'id' => 'days_in_stock',
                'name' => 'Days in stock',
                'icon' => 'truck-clock',
            ],
            [
                'id' => 'days_since_update',
                'name' => 'Days since last update',
                'icon' => 'reply-clock',
            ],
            [
                'id' => 'has_description',
                'name' => 'Has description',
                'icon' => 'text',
            ],
            [
                'id' => 'has_attention_grabber',
                'name' => 'Has attention grabber',
                'icon' => 'text',
            ],
            [
                'id' => 'at_publish_advert',
                'name' => 'AutoTrader publish advert',
                'enabled' => Settings::get('sales-channels-auto-trader-enabled'),
            ],
        ])
            ->filter(fn($column) => $column['enabled'] ?? true)
            ->values()
            ->toArray();
    }

    private function formatStockProvider(?string $stockProvider): string
    {
        if ($stockProvider === null) {
            return 'Admin';
        }

        // Handle import map providers (format: import-map-{id})
        if (str_starts_with($stockProvider, 'import-map-')) {
            $importMapId = (int) str_replace('import-map-', '', $stockProvider);
            $importMap = ImportMap::query()->find($importMapId);
            return $importMap?->name ?? 'Import Map';
        }

        $integrationRepository = App::make(IntegrationRepository::class);
        $integration = $integrationRepository->getAllForType('stock')
            ->first(fn($integration, $key) => $key === $stockProvider);

        return $integration && isset($integration['class'])
            ? App::make($integration['class'])->name()
            : ucwords(str_replace('-', ' ', $stockProvider));
    }

    private function getVehicleImageSrc(Vehicle $vehicle): ?string
    {
        $previewImage = $vehicle->getPreviewImage('mini-thumb');

        if ($previewImage !== null) {
            return $previewImage;
        }

        if (!$this->isImaginPlaceholderEnabled()) {
            return null;
        }

        return $this->getImaginPlaceholderUrl($vehicle);
    }

    private function isImaginPlaceholderEnabled(): bool
    {
        return Feature::isEnabled('imagin-studio-placeholders')
            && Settings::get('imagin-placeholders-vehicle-enabled', false)
            && !empty(Settings::get('imagin-placeholders-client-key', ''));
    }

    private function getImaginPlaceholderUrl(Vehicle $vehicle): ?string
    {
        $make = $vehicle->make?->name;
        $model = $vehicle->model?->name;

        if (empty($make) || empty($model)) {
            return null;
        }

        $query = http_build_query([
            'customer' => Settings::get('imagin-placeholders-client-key', ''),
            'make' => strtolower($make),
            'modelFamily' => strtolower($model),
            'modelVariant' => $vehicle->derivative,
            'modelYear' => $vehicle->manufacture_year,
            'powerTrain' => $vehicle->fuelType?->name,
            'transmission' => $vehicle->transmissionType?->name,
            'bodySize' => $vehicle->bodyStyle?->name,
            'paintdescription' => $vehicle->colour,
            'aspectRatio' => '16:9',
            'angle' => Settings::get('imagin-studio-angle', 1),
            'zoomLevel' => 90
        ]);

        return 'https://cdn.imagin.studio/getImage?' . $query;
    }
}
