<?php

namespace App\Http\Resources;

use App\Facades\Feature;
use App\Facades\Settings;
use App\Modules\PlaceholderImages\ImaginStudio;
use App\OfferRepository;
use App\Traits\GetsFormResource;
use App\Traits\HasPlaceholderImage;
use App\Traits\MediaHasSizes;
use App\Traits\RetrievesContent;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;
use Mtc\MercuryDataModels\CarConfiguratorModel;
use Mtc\MercuryDataModels\Traits\HasVehicleCustomAttributes;
use Mtc\MercuryDataModels\VehicleOffer;

class NewCarResource extends JsonResource
{
    use HasPlaceholderImage;
    use FranchiseData;
    use PhoneNumberDisplay;
    use RetrievesContent;
    use MediaHasSizes;
    use GetsFormResource;
    use HasVehicleCustomAttributes;

    public static $wrap = '';

    private const UI_RESOURCE_PREFIX = 'App\\Http\\Resources\\';

    /**
     * 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([
            'mediaUses.media',
            'transmission',
            'fuelTypes',
            'attributeValues',
            'bodyStyle',
            'drivetrain',
            'finance',
            'form.sections.questions',
            'testDriveForm.sections.questions',
            'content.mediaUses.media',
            'content.subContent.mediaUses.media',
            'content.subContent.subContent.mediaUses.media',
            'content.subContent.subContent.subContent.mediaUses.media',
            'content.contentElement',
            'content.globalContent.contentElement',
            'content.subContent.contentElement',
            'content.subContent.globalContent.contentElement',
            'content.subContent.subContent.contentElement',
            'content.subContent.subContent.globalContent.contentElement',
            'content.subContent.subContent.subContent.contentElement',
            'content.subContent.subContent.subContent.globalContent.contentElement',
            'content.subContent.subContent.subContent.subContent.contentElement',
            'content.subContent.subContent.subContent.subContent.globalContent.contentElement',
            'trims.mediaUses.media',
        ]);

        $this->resource->make_name = $this->resource->make?->name;
        $this->resource->make_slug = $this->resource->make?->slug;
        $this->resource->model_name = $this->resource->model?->name;
        $this->resource->model_slug = $this->resource->model?->slug;
        $this->resource->model_id = $this->resource->model?->id;
        $this->resource->view_stock = false;

        $this->resource->forms = [
            'enquire' => $this->resource->form_id
                ? (new FormViewResource($this->resource->form))->setValues([
                    'new_car_id' => $this->resource->id,
                    'dealership_id' => $this->getDealershipValue(),
                    'franchise_id' => $this->resource->franchise_id,
                ])
                : null,
            'test_drive' => $this->resource->test_drive_form_id
                ? (new FormViewResource($this->resource->testDriveForm))
                    ->setValues([
                        'new_car_id' => $this->resource->id,
                        'dealership_id' => $this->getDealershipValue(),
                        'franchise_id' => $this->resource->franchise_id,
                    ])
                : $this->getResourceForFormByEnquiryType(
                    Settings::get('form-enquiry-type-test-drive') ?? '',
                    'new_car_id',
                    [
                        'new_car_id' => $this->resource->id,
                        'dealership_id' => $this->getDealershipValue(),
                        'franchise_id' => $this->resource->franchise_id,
                    ]
                ),
        ];

        $resource = $this->resource->only([
            'id',
            'name',
            'price',
            'monthly_price',
            'make_name',
            'make_slug',
            'model_name',
            'model_slug',
            'derivative',
            'content',
            'media_uses',
            'forms',
            'finance',
            'specs',
            'features',
            'hero',
            'excerpt',
            'vehicle_type',
            'brochure_url',
        ]);

        $resource['media_uses'] = $this->getGallery($this->resource);
        $resource['details'] = $this->getDetails();
        $resource['contact_number'] = $this->getContactNumber();
        $resource['content'] = $this->getContent($this->resource->content);
        $resource['seo'] = $this->fillSeo(
            'new-car',
            $request->header('x-path') ?? '/new/' . $this->resource->slug
        );
        $resource['social_meta'] = new SocialMetaResource($resource['seo']);
        $resource['isFranchise'] = $this->isFranchise();
        $resource['franchise'] = $this->franchiseData();
        $resource['pageContent'] = [
            'title' => __('automotive.new_cars_for_make', ['make' => $this->resource->make_name]),
            'description' => '',
        ];
        $resource['extra'] = $this->getExtraData($this->resource);
        $resource['custom'] = $this->resource->getAllCustom();

        if (Feature::isEnabled('car-configurator')) {
            $configurator_models = CarConfiguratorModel::query()
                ->where('active', 1)
                ->where('make_id', $this->resource->make_id)
                ->where('model_id', $this->resource->model_id)
                ->get();
            if ($configurator_models->whereNotNull('fuel_type_id')->count()) {
                $resource['configurator'] = $configurator_models
                    ->filter(fn(CarConfiguratorModel $model) => $this->resource->fuelTypes
                        ->filter(fn($fuelType) => $fuelType->id == $model->fuel_type_id)->isNotEmpty())
                    ->map(fn($item) => $item->only(['name', 'slug']))
                    ->values();
            } else {
                $resource['configurator'] = $configurator_models->map(fn($item) => $item->only(['name', 'slug']));
            }
        }
        if ($this->resource->model_id) {
            $resource['cross_sell'] = [
                'name' => __('automotive.cross-sell.offers', ['model' => $this->resource->model_name]),
                'items' => (new OfferRepository())->featuredByModel($this->resource->model_id),
            ];
        }

        $resource['has_offers'] = VehicleOffer::query()
            ->where('make_id', $this->resource->make_id)
            ->where('model_id', $this->resource->model_id)
            ->active()
            ->exists();

        $resource['trims'] = $this->resource->getTrims()->map(function ($trim) {
            return array_merge(
                $trim->toArray(),
                [
                    'image' => $this->getGallery($trim, false, true)?->first(),
                ],
                [
                    'listing_image' => $this->getGallery($trim, false, false)?->first(),
                ]
            );
        });

        $resource['imagin_studio_base_url'] = Feature::isEnabled('imagin-studio-placeholders')
            ? (new ImaginStudio())->getBaseUrl()
            : null;

        return $resource;
    }

    protected function getGallery(Model $model, bool $require_hero = true, ?bool $require_primary = null): ?Collection
    {
        if (is_null($model->mediaUses) || $model->mediaUses->isEmpty()) {
            return $this->getPlaceholderForGallery($model);
        }

        return $model->mediaUses
            ->when($require_hero, fn($query) => $query->filter(
                fn($mediaUse) => ($mediaUse->flags['hero'] ?? null)
                    || ($mediaUse->flags['mobile_hero'] ?? null)
            ))
            ->when(!is_null($require_primary), fn($query) => $query->where('primary', $require_primary))
            ->map(function ($mediaUse) {
                $mediaUse->setOverrideOwnerType('new-car');

                return [
                    'id' => $mediaUse->id,
                    'hex1' => $mediaUse->media->hex1,
                    'hex2' => $mediaUse->media->hex2,
                    'title' => $mediaUse->title,
                    'alt_text' => $mediaUse->alt_text,
                    'description' => $mediaUse->description,
                    'caption' => $mediaUse->caption,
                    'src' => $mediaUse->getUrl($this->largeImageDimensions()),
                    'src_large' => $mediaUse->getUrl($this->mediumImageDimensions()),
                    'type' => $mediaUse->media->type,
                    'original' => $mediaUse->media->getOriginalUrlAttribute(),
                    'sizes' => $this->allSizesForUse($this->resource, $mediaUse, 'new-car'),
                ];
            })
            ->values();
    }

    private function getDetails(): array
    {
        $fuelTypes = null;
        if ($this->resource->fuelTypes->count() == 1) {
            $fuelTypes = $this->resource->fuelTypes->first()->name;
        } elseif ($this->resource->fuelTypes->count() > 1) {
            $fuelTypes = $this->resource->fuelTypes->pluck('name');
        }

        return [
            [
                'name' => __('labels.vehicle.colour'),
                'value' => $this->resource->colour,
            ],
            [
                'name' => __('labels.vehicle.engine_size'),
                'value' => $this->resource->engine_size_cc
                    ? $this->resource->engine_size_cc . 'cc'
                    : null,
            ],
            [
                'name' => __('labels.vehicle.fuel_type'),
                'value' => $fuelTypes,
            ],
            [
                'name' => __('labels.vehicle.body_style'),
                'value' => $this->resource->bodyStyle?->name,
            ],
            [
                'name' => __('labels.vehicle.transmission'),
                'value' => $this->resource->transmission?->name,
            ],
            [
                'name' => __('labels.vehicle.drivetrain'),
                'value' => $this->resource->drivetrain?->name,
            ],
        ];
    }

    protected function largeImageDimensions(): string
    {
        return 'full-width-banner';
    }

    protected function mediumImageDimensions(): string
    {
        return 'full-width-banner';
    }

    protected function thumbnailImageDimensions(): string
    {
        return 'full-width-banner';
    }

    private function getDealershipValue(): ?int
    {
        if ($this->resource->dealership_id) {
            return $this->resource->dealership_id;
        }

        return $this->resource->franchise?->dealerships()->first()?->id;
    }
}
