<?php

namespace App\Http\Controllers;

/*
 * CatalogController — публичный каталог и страница автомобиля.
 *
 * Кеш: plain array (не объекты) → без __PHP_Incomplete_Class при unserialize.
 * Ключ кеша включает все параметры фильтра + страницу пагинации.
 * filterOptions() кешируется отдельно — пересобирать при каждом запросе дорого.
 */

use App\Models\Car;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class CatalogController extends Controller
{
    private const CACHE_TTL = 86400; // 24 часа

    private const PER_PAGE = 12;

    public function index(Request $request): View
    {
        // ── Читаем фильтры из GET ──────────────────────────────────────
        $conditions = array_filter((array) $request->input('condition', []));
        $countries = array_filter((array) $request->input('country_origin', []));
        $fuels = array_filter((array) $request->input('engine_type', []));
        $make = trim((string) $request->input('make', ''));
        $bodyType = trim((string) $request->input('body_type', ''));
        $priceTo = $request->filled('price_to') ? (int) $request->input('price_to') : null;
        $priceFrom = null;

        // price_range из быстрого подбора: "1500000", "1500000-3000000", "5000000-"
        $priceRange = $request->input('price_range', '');
        if ($priceRange !== '') {
            if (str_ends_with($priceRange, '-')) {
                $priceFrom = (int) rtrim($priceRange, '-') ?: null;
            } elseif (str_contains($priceRange, '-')) {
                [$from, $to] = explode('-', $priceRange, 2);
                $priceFrom = $from !== '' ? (int) $from : null;
                $priceTo   = $to   !== '' ? (int) $to   : $priceTo;
            } else {
                $priceTo = (int) $priceRange ?: $priceTo;
            }
        }

        $year = $request->filled('year') ? (int) $request->input('year') : null;
        $sort = $request->input('sort', '');
        $page = $request->integer('page', 1);

        // ── Строим ключ кеша ──────────────────────────────────────────
        $filterData = compact('conditions', 'countries', 'fuels', 'make', 'bodyType', 'priceFrom', 'priceTo', 'year', 'sort');
        ksort($filterData);
        $cacheKey = 'catalog.'.md5(serialize($filterData)).'.p'.$page;

        $cached = Cache::remember($cacheKey, self::CACHE_TTL, function () use (
            $conditions, $countries, $fuels, $make, $bodyType, $priceFrom, $priceTo, $year, $sort, $page
        ) {
            $query = Car::where('status', 'active');

            if ($conditions) {
                $query->whereIn('condition', $conditions);
            }
            if ($countries) {
                $query->whereIn('country_origin', $countries);
            }
            if ($fuels) {
                $query->whereIn('engine_type', $fuels);
            }
            if ($make) {
                $query->where('make', $make);
            }
            if ($bodyType) {
                $query->where('body_type', $bodyType);
            }
            if ($priceFrom) {
                $query->where('price_rub', '>=', $priceFrom);
            }
            if ($priceTo) {
                $query->where('price_rub', '<=', $priceTo);
            }
            if ($year) {
                $query->where('year', $year);
            }

            match ($sort) {
                'price_asc' => $query->orderBy('price_rub'),
                'price_desc' => $query->orderByDesc('price_rub'),
                'year_desc' => $query->orderByDesc('year'),
                default => $query->orderByDesc('id'),
            };

            $paginator = $query->paginate(self::PER_PAGE, ['*'], 'page', $page);

            return [
                'total' => $paginator->total(),
                'items' => $paginator->getCollection()->map->getAttributes()->all(),
            ];
        });

        // Восстанавливаем Car из атрибутов (без unserialize объекта)
        $items = collect($cached['items'])->map(fn ($a) => (new Car)->setRawAttributes($a, true));
        $cars = new LengthAwarePaginator(
            $items, $cached['total'], self::PER_PAGE, $page,
            ['path' => $request->url(), 'query' => $request->query()]
        );

        $filterOptions = $this->filterOptions();
        $activeFilters = compact('conditions', 'countries', 'fuels', 'make', 'bodyType', 'priceFrom', 'priceTo', 'year', 'sort');

        return view('pages.catalog', compact('cars', 'filterOptions', 'activeFilters'));
    }

    public function show(int $id): View
    {
        // Детальная страница: без кеша — запросы редкие, зато данные всегда свежие
        $car = Car::where('status', 'active')->findOrFail($id);

        $similar = Car::where('status', 'active')
            ->where('id', '!=', $car->id)
            ->where(fn ($q) => $q->where('make', $car->make)->orWhere('body_type', $car->body_type))
            ->orderByDesc('id')
            ->limit(3)
            ->get();

        return view('pages.car', compact('car', 'similar'));
    }

    // Опции для фильтров — кешируются отдельно
    private function filterOptions(): array
    {
        return Cache::remember('catalog_filter_opts', self::CACHE_TTL, function () {
            $base = Car::where('status', 'active');

            return [
                'makes' => (clone $base)->select('make')->distinct()->orderBy('make')->pluck('make')->toArray(),
                'body_types' => (clone $base)->whereNotNull('body_type')->where('body_type', '!=', '')->select('body_type')->distinct()->orderBy('body_type')->pluck('body_type')->toArray(),
                'countries' => (clone $base)->whereNotNull('country_origin')->select('country_origin')->distinct()->orderBy('country_origin')->pluck('country_origin')->toArray(),
                'years' => (clone $base)->select('year')->distinct()->orderByDesc('year')->pluck('year')->toArray(),
                'price_min' => (int) ((clone $base)->whereNotNull('price_rub')->min('price_rub') ?? 0),
                'price_max' => (int) ((clone $base)->whereNotNull('price_rub')->max('price_rub') ?? 50000000),
            ];
        });
    }
}
