<?php

namespace App\Http\Resources;

use App\Traits\HasPlaceholderImage;
use App\Traits\MediaHasSizes;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\Traits\HasVehicleCustomAttributes;
use Mtc\MercuryDataModels\VehicleOffer;

class NewCarListResource extends JsonResource
{
    use HasPlaceholderImage;
    use MediaHasSizes;
    use HasVehicleCustomAttributes;

    public static $wrap = '';

    private Collection $placeholder;
    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        $this->resource->load(['attributeValues']);

        if ($this->resource instanceof LengthAwarePaginator) {
            $this->resource->through(fn(NewCar $car) => $this->map($car));
        } else {
            $this->resource = $this->resource->map(fn(NewCar $car) => $this->map($car));
        }
        return parent::toArray($request);
    }

    protected function map(NewCar $car): array
    {
        $fuelTypes = null;
        if ($car->fuelTypes->count() == 1) {
            $fuelTypes = $car->fuelTypes->first()->name;
        } elseif ($car->fuelTypes->count() > 1) {
            $fuelTypes = $car->fuelTypes->pluck('name');
        }

        $previewImage = $car->mediaUses
            ->filter(fn ($mediaUse) => $mediaUse->flags['listing'] ?? null)
            ->first();
        $heroImage = $car->mediaUses
            ->filter(fn ($mediaUse) => $mediaUse->flags['hero'] ?? null)
            ->first();

        $mobileHeroImage = $car->mediaUses
            ->filter(fn ($mediaUse) => $mediaUse->flags['mobile_hero'] ?? null)
            ->first();

        $imageSizes = !empty($previewImage)
            ? $this->allSizesForUse($car, $previewImage)
                ->put('original', $previewImage->media->getOriginalUrlAttribute())
            : [];

        $heroImageSizes = !empty($heroImage)
            ? $this->allSizesForUse($car, $heroImage)
                ->put('original', $heroImage->media->getOriginalUrlAttribute())
            : [];

        $mobileHeroImageSizes = !empty($mobileHeroImage)
            ? $this->allSizesForUse($car, $mobileHeroImage)
                ->put('original', $mobileHeroImage->media->getOriginalUrlAttribute())
            : [];

        return [
            'slug' => $car->slug,
            'name' => $car->name,
            'excerpt' => $car->excerpt,
            'derivative' => $car->derivative,
            'make' => $car->make?->name,
            'model' => $car->model?->name,
            'image' => $this->getPreviewImage($car, 'tile', 'listing'),
            'image_sizes' => $imageSizes,
            'images' => [
                'listing' => [
                    'id' => $previewImage?->id,
                    'title' => $previewImage?->title,
                    'alt_text' => $previewImage?->alt_text,
                    'description' => $previewImage?->description,
                    'caption' => $previewImage?->caption,
                    'interior' => $previewImage?->interior,
                    'exterior' => $previewImage?->exterior,
                    'hex1' => $previewImage?->media?->hex1,
                    'hex2' => $previewImage?->media?->hex2,
                    'type' => $previewImage?->media->type,
                    'src' => $previewImage?->media->getOriginalUrlAttribute(),
                    'sizes' => $imageSizes,
                ],
                'hero' => [
                    'id' => $heroImage?->id,
                    'title' => $heroImage?->title,
                    'alt_text' => $heroImage?->alt_text,
                    'description' => $heroImage?->description,
                    'caption' => $heroImage?->caption,
                    'interior' => $heroImage?->interior,
                    'exterior' => $heroImage?->exterior,
                    'hex1' => $heroImage?->media?->hex1,
                    'hex2' => $heroImage?->media?->hex2,
                    'type' => $heroImage?->media->type,
                    'src' => $heroImage?->media->getOriginalUrlAttribute(),
                    'sizes' => $heroImageSizes,
                ],
                'mobile_hero' => [
                    'id' => $mobileHeroImage?->id,
                    'title' => $mobileHeroImage?->title,
                    'alt_text' => $mobileHeroImage?->alt_text,
                    'description' => $mobileHeroImage?->description,
                    'caption' => $mobileHeroImage?->caption,
                    'interior' => $mobileHeroImage?->interior,
                    'exterior' => $mobileHeroImage?->exterior,
                    'hex1' => $mobileHeroImage?->media?->hex1,
                    'hex2' => $mobileHeroImage?->media?->hex2,
                    'type' => $mobileHeroImage?->media->type,
                    'src' => $mobileHeroImage?->media->getOriginalUrlAttribute(),
                    'sizes' => $mobileHeroImageSizes,
                ],
            ],
            'hero_image' => $this->getPreviewImage($car, 'tile', 'hero'),
            'price' => $car->price,
            'monthly_price' => $car->monthly_price,
            'section_url' => $car->make?->slug . '/' . $car->model?->slug,
            'fuel_type' => $fuelTypes,
            'colour' => $car->colour,
            'fuel_types' => $car->getAvailableFuelTypes(),
            'from_price' => $this->getFromPriceFromOffers($car),
            'extra' => $this->getExtraData($car),
        ];
    }

    public function getPreviewImage(Model $model, string $dimensions, string $type): ?string
    {
        $listingImage = $model->mediaUses
            ->filter(fn ($mediaUse) => $mediaUse->flags[$type] ?? null)
            ->first();

        return $listingImage?->getUrl($dimensions) ?? $this->getPlaceholder($model, $dimensions);
    }

    protected function largeImageDimensions(): string
    {
        return 'tile';
    }

    protected function mediumImageDimensions(): string
    {
        return $this->largeImageDimensions();
    }

    protected function thumbnailImageDimensions(): string
    {
        return $this->largeImageDimensions();
    }

    protected function getFromPriceFromOffers(NewCar $car): ?float
    {
        return VehicleOffer::query()
            ->where('make_id', '=', $car->make_id)
            ->where('model_id', '=', $car->model_id)
            ->where('price', '>', 0)
            ->orderBy('price')
            ->pluck('price')
            ->first();
    }
}
