<?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\RetrievesContent;
use Illuminate\Http\Resources\Json\JsonResource;
use Mtc\MercuryDataModels\CarConfiguratorModel;
use Mtc\MercuryDataModels\Traits\HasVehicleCustomAttributes;

class OfferResource extends JsonResource
{
    use HasPlaceholderImage;
    use FranchiseData;
    use PhoneNumberDisplay;
    use RetrievesContent;
    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',
            'finance',
            'transmission',
            'fuelType',
            'attributeValues',
            'bodyStyle',
            'drivetrain',
            'specs',
            'features',
            'equipment',
            '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.contentElement',
            'content.subContent.subContent.subContent.globalContent.contentElement',
        ]);

        $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->view_stock = false;

        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->count() > 1 && !empty($this->resource->fuel_type_id)) {
                $this->resource->configurator_slug = $configurator_models
                    ->filter(fn(CarConfiguratorModel $model) => $model->fuel_type_id == $this->resource->fuel_type_id)
                    ->first()
                    ?->slug;
            } else {
                $this->resource->configurator_slug = $configurator_models->first()?->slug;
            }
        }

        $this->resource->forms = [
            'enquire' => $this->getResourceForForm(
                $this->resource->form,
                [
                    'offer_id' => $this->resource->id,
                    'dealership_id' => $this->getDealershipValue(),
                ]
            ),
            'test_drive' => $this->resource->test_drive_form_id
                ? $this->getResourceForForm($this->resource->testDriveForm, [
                    'offer_id' => $this->resource->id,
                    'dealership_id' => $this->getDealershipValue(),
                ])
                : $this->getResourceForFormByEnquiryType(
                    Settings::get('form-enquiry-type-test-drive') ?? '',
                    'offer_id',
                    [
                        'offer_id' => $this->resource->id,
                        'dealership_id' => $this->getDealershipValue(),
                    ]
                ),
        ];

        $this->resource->features = $this->resource->features->pluck('name');

        if ($this->resource->dealership) {
            $this->resource->dealership->address = collect([
                $this->resource->dealership->address1,
                $this->resource->dealership->address2,
                $this->resource->dealership->city,
                $this->resource->dealership->postcode,
            ])->filter()->implode(', ');
        }

        $resource = $this->resource->only([
            'id',
            'name',
            'price',
            'full_price',
            'deposit',
            'make_id',
            'model_id',
            'make_name',
            'model_name',
            'make_slug',
            'model_slug',
            'derivative',
            'content',
            'media_uses',
            'forms',
            'finance',
            'excerpt',
            'label',
            'colour',
            'mpg',
            'co2',
            'battery_range',
            'configurator_slug',
            'battery_capacity_kwh',
            'battery_usable_capacity_kwh',
            'battery_charge_time',
            'battery_quick_charge_time',
            'battery_quick_charge_level',
            'engine_size_cc',
            'key_features',
            'standard_spec',
            'technical_spec',
            'description',
            't_and_cs',
            'youtube_video',
            'trim',
            'cta_button1_label',
            'cta_button1_url',
            'cta_button2_label',
            'cta_button2_url',
            'footnote',
            'cap_id',
            'new_car_id',
            'trim_id',
        ]);

        $resource['images'] = $resource['media_uses'] = $this->getGallery($this->resource);
        $resource['details'] = $this->getDetails();

        $resource['cross_sell'] = (new OfferRepository())->similar($this->resource);
        $resource['contact_number'] = $this->getContactNumber();
        $resource['content'] = $this->getContent($this->resource->content);
        $resource['seo'] = $this->fillSeo('offer', $request->header('x-path'));
        $resource['social_meta'] = new SocialMetaResource($resource['seo']);
        $resource['isFranchise'] = $this->isFranchise();
        $resource['franchise'] = $this->franchiseData();
        $resource['specs'] = $this->resource->specs
            ->map(fn($entry) => $entry->only(['description', 'category', 'value']));
        $resource['features'] = $this->resource->features;
        $resource['equipment'] = $this->resource->equipment
            ->map(fn($entry) => $entry->only(['type', 'code', 'description', 'category', 'price']));
        $resource['offer_type_slug'] = $this->offerType?->slug;
        $resource['dealership'] = $this->resource->dealership?->only([
            'id',
            'slug',
            'name',
            'contact_no',
            'address',
            'is_open',
            'opens_at',
            'closes_at',
            'franchise',
            'location_stock',
        ]);

        $resource['fuel_type'] = $this->resource->fuelType?->name;
        $resource['transmission_type'] = $this->resource->transmission?->name;
        $resource['mpg'] = $this->resource->mpg;
        $resource['apr'] = $this->resource->cheapestFinance?->apr;
        $resource['monthly_price'] = $this->resource->cheapestFinance?->monthly_price;
        $resource['monthly_price_type'] = $this->resource->cheapestFinance?->finance_type;
        $resource['type'] = $this->resource->new_car_type;
        $resource['body_style'] = $this->resource->bodyStyle?->name;
        $resource['finance'] = $this->getFinanceExamples($this->resource->finance);
        $resource['finance_defaults'] = [
            'deposit' => Settings::get('offers-finance-deposit_percentage'),
            'term' => Settings::get('offers-finance-term'),
            'annual_mileage' => Settings::get('offers-finance-annual_mileage'),
            'credit_rating' => Settings::get('offers-finance-credit_rating'),
        ];
        $resource['imagin_studio_base_url'] = Feature::isEnabled('imagin-studio-placeholders')
            ? (new ImaginStudio())->getBaseUrl()
            : null;
        $resource['extra'] = $this->getExtraData($this->resource);

        if ($this->resource->template?->slug) {
            $resource['template_slug'] = $this->resource->template->slug;
        }

        return $resource;
    }

    private function getDetails(): array
    {
        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' => $this->resource->fuelType?->name
            ],
            [
                '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
            ],
        ];
    }

    private function getFinanceExamples($finance)
    {
        $financeExamples = [];

        foreach ($finance as $financeExample) {
            $financeExamples[$financeExample->finance_type] = $financeExample;
        }

        return $financeExamples;
    }

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

    protected function mediumImageDimensions(): string
    {
        return 'medium';
    }

    protected function thumbnailImageDimensions(): string
    {
        return 'medium';
    }

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

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