<?php

namespace App\Http\Controllers;

use App\CatalogOfferMatcher;
use App\Facades\Feature;
use App\Filter;
use App\Http\Requests\NewCarSearchRequest;
use App\Http\Requests\ViewNewCarRequest;
use App\Http\Resources\NewCarListResource;
use App\Http\Resources\NewCarResource;
use App\Modules\PlaceholderImages\ImaginStudio;
use App\Traits\CacheObject;
use App\Traits\ModelsForMakeInSearch;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Mtc\MercuryDataModels\CatalogOffer;
use Mtc\MercuryDataModels\NewCar;

class NewCarController extends Controller
{
    use ModelsForMakeInSearch;
    use CacheObject;

    public function search(NewCarSearchRequest $request, ?string $make = null): array
    {
        $makeModel = $make ? Filter::matchSlugToRecord('make', $make) : null;
        $vehicleModel = $request->filled('model_id')
            ? Filter::matchSlugToRecord('model', $request->input('model_id'))
            : null;

        $baseQuery = NewCar::query()
            ->whereHas('make')
            ->whereHas('model')
            ->when($makeModel, fn($query) => $query->where('make_id', $makeModel->id))
            ->when($request->filled('body_type'), fn($query) => $query->whereHas(
                'bodyStyle',
                fn($query) => $query->where('slug', $request->input('body_type'))
            ))
            ->when($request->filled('fuel_type'), fn($query) => $query->whereHas(
                'fuelTypes',
                fn($query) => $query->whereIn('slug', $request->input('fuel_type'))
            ))
            ->when($request->filled('franchise'), fn($query) => $query->whereHas(
                'franchise',
                fn($query) => $query->where('slug', $request->input('franchise'))
            ))
            ->when($request->filled('vehicle_type'), fn($query) => $query->where(
                'vehicle_type',
                $request->input('vehicle_type')
            ))
            ->whereModelSlug($request->input('model_id'))
            ->active();

        $cars = (clone $baseQuery)
            ->with([
                'mediaUses.media',
                'make',
                'model',
                'fuelTypes',
            ])
            ->setSortBy($request->input('sort_by'))
            ->paginate($request->input('per_page', 15));

        return [
            'make' => $makeModel?->name,
            'make_slug' => $makeModel?->slug,
            'model' => $vehicleModel?->name,
            'model_slug' => $vehicleModel?->slug,
            'models' => $makeModel ? $this->getModelsForMake(
                $makeModel->id,
                'newCars',
                null,
                $request->input('vehicle_type')
            ) : [],
            'offers' => new NewCarListResource($cars),
            'catalog_offers' => $this->getNewCarCatalogOffers($baseQuery),
            'content' => [
                'title' => $makeModel
                    ? __('automotive.new_cars_for_make', ['make' => $makeModel->name])
                    : __('automotive.new_cars'),
                'description' => '',
            ],
            'imagin_studio_base_url' => Feature::isEnabled('imagin-studio-placeholders')
                ? (new ImaginStudio())->getBaseUrl()
                : null,
        ];
    }

    public function show(ViewNewCarRequest $request): NewCarResource|JsonResponse
    {
        $car = $request->getNewCar();
        if (!$car) {
            abort(404);
        }
        $cache_path = 'new-car-' . $request->getRequestUri();
        return $this->cache($cache_path, 1, fn() => (new NewCarResource($car))->toResponse($request));
    }

    private function getNewCarCatalogOffers(Builder $currentQuery): array
    {
        $offers = CatalogOffer::query()
            ->active()
            ->forNewCars()
            ->with(['mediaUses.media', 'rules'])
            ->get();

        return (new CatalogOfferMatcher($currentQuery))
            ->getMatchingOffers($offers)
            ->map(fn(CatalogOffer $offer) => [
                'id' => $offer->id,
                'name' => $offer->name,
                'subtitle' => $offer->subtitle,
                'link' => $offer->link,
                'button_text' => $offer->button_text,
                'image' => $offer->primaryMedia?->url,
            ])
            ->values()
            ->toArray();
    }
}
