<?php

namespace App\Http\Controllers;

use App\Filter;
use App\Http\Requests\ViewVehicleTrimRequest;
use Illuminate\Http\Request;
use App\Http\Resources\VehicleTrimResource;
use App\Http\Resources\VehicleTrimSearchListResource;
use App\Traits\CacheObject;
use Illuminate\Database\Eloquent\Builder;
use Mtc\MercuryDataModels\Filters\VehicleAttributeBooleanFilter;
use Mtc\MercuryDataModels\Filters\VehicleAttributeValueMaxFilter;
use Mtc\MercuryDataModels\Filters\VehicleAttributeValueMinFilter;
use Mtc\MercuryDataModels\VehicleAttribute;
use Mtc\MercuryDataModels\VehicleTrim;

class VehicleTrimController extends Controller
{
    use CacheObject;

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

        $query = VehicleTrim::query()
            ->where('active', true)
            ->whereHas('newCar', fn (Builder $q) => $q->active())
            ->whereHas('make')
            ->whereHas('model')
            ->when($makeModel, fn (Builder $q) => $q->where('make_id', $makeModel->id))
            ->when($vehicleModel, fn (Builder $q) => $q->where('model_id', $vehicleModel->id));

        $this->applyAttributeFilters($query, $request->all());

        $trims = $query
            ->with([
                'mediaUses.media',
                'make',
                'model',
                'newCar',
                'attributeValues',
            ])
            ->orderBy('order')
            ->paginate($request->input('per_page', 15));

        return new VehicleTrimSearchListResource($trims);
    }

    public function show(ViewVehicleTrimRequest $request): VehicleTrimResource
    {
        return new VehicleTrimResource($request->getTrim());
    }

    private function applyAttributeFilters(Builder $query, array $params): void
    {
        $morphClass = (new VehicleTrim())->getMorphClass();

        $filterableAttributes = VehicleAttribute::query()
            ->where('filterable', 1)
            ->where('model', $morphClass)
            ->get();

        foreach ($filterableAttributes as $attribute) {
            if ($attribute->type === 'boolean' && isset($params[$attribute->slug])) {
                (new VehicleAttributeBooleanFilter($attribute->slug, VehicleTrim::class))
                    ->applyFilter($query, (array) $params[$attribute->slug]);
            } elseif (in_array($attribute->type, ['number', 'integer'])) {
                if (isset($params[$attribute->slug . '_min'])) {
                    (new VehicleAttributeValueMinFilter($attribute->slug . '_min', VehicleTrim::class))
                        ->applyFilter($query, (array) $params[$attribute->slug . '_min']);
                }
                if (isset($params[$attribute->slug . '_max'])) {
                    (new VehicleAttributeValueMaxFilter($attribute->slug . '_max', VehicleTrim::class))
                        ->applyFilter($query, (array) $params[$attribute->slug . '_max']);
                }
            }
        }
    }
}
