<?php

namespace App\Livewire;

use App\Models\Ride;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Cache;
use Livewire\Attributes\Url;

class RidesListing extends Component
{
    use WithPagination;

    // Search and filter properties with URL binding for deep linking
    #[Url(as: 'q')]
    public string $search = '';

    #[Url(as: 'category')]
    public string $category = '';

    #[Url(as: 'status')]
    public string $status = '';

    #[Url(as: 'manufacturer')]
    public string $manufacturerId = '';

    #[Url(as: 'year_from')]
    public string $openingYearFrom = '';

    #[Url(as: 'year_to')]
    public string $openingYearTo = '';

    #[Url(as: 'min_height')]
    public string $minHeight = '';

    #[Url(as: 'max_height')]
    public string $maxHeight = '';

    #[Url(as: 'park')]
    public string $parkId = '';

    // Performance optimization
    protected $queryString = [
        'search' => ['except' => ''],
        'category' => ['except' => ''],
        'status' => ['except' => ''],
        'manufacturerId' => ['except' => ''],
        'openingYearFrom' => ['except' => ''],
        'openingYearTo' => ['except' => ''],
        'minHeight' => ['except' => ''],
        'maxHeight' => ['except' => ''],
        'parkId' => ['except' => ''],
        'page' => ['except' => 1],
    ];

    /**
     * Component initialization
     */
    public function mount(): void
    {
        // Initialize component state
    }

    /**
     * Reset pagination when search/filters change
     */
    public function updatedSearch(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedCategory(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedStatus(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedManufacturerId(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedOpeningYearFrom(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedOpeningYearTo(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedMinHeight(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedMaxHeight(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    public function updatedParkId(): void
    {
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    /**
     * Clear all filters
     */
    public function clearFilters(): void
    {
        $this->reset([
            'search',
            'category',
            'status',
            'manufacturerId',
            'openingYearFrom',
            'openingYearTo',
            'minHeight',
            'maxHeight',
            'parkId'
        ]);
        $this->resetPage();
        $this->invalidateCache('rides');
    }

    /**
     * Get rides with Django parity search and filtering
     */
    public function getRidesProperty()
    {
        $cacheKey = $this->getCacheKey('rides.' . md5(serialize([
            'search' => $this->search,
            'category' => $this->category,
            'status' => $this->status,
            'manufacturerId' => $this->manufacturerId,
            'openingYearFrom' => $this->openingYearFrom,
            'openingYearTo' => $this->openingYearTo,
            'minHeight' => $this->minHeight,
            'maxHeight' => $this->maxHeight,
            'parkId' => $this->parkId,
            'page' => $this->getPage(),
        ])));

        return $this->remember($cacheKey, function () {
            return $this->buildQuery()->paginate(12);
        }, 300); // 5 minute cache
    }

    /**
     * Build the query with Django parity search and filters
     */
    protected function buildQuery()
    {
        $query = Ride::query()
            ->with(['park', 'manufacturer', 'designer', 'photos' => function ($q) {
                $q->where('is_featured', true)->limit(1);
            }]);

        // Django parity multi-term search
        if (!empty($this->search)) {
            $terms = explode(' ', trim($this->search));
            foreach ($terms as $term) {
                $query->where(function ($subQuery) use ($term) {
                    $subQuery->where('name', 'ilike', "%{$term}%")
                            ->orWhere('description', 'ilike', "%{$term}%")
                            ->orWhereHas('park', fn($q) => $q->where('name', 'ilike', "%{$term}%"))
                            ->orWhereHas('manufacturer', fn($q) => $q->where('name', 'ilike', "%{$term}%"))
                            ->orWhereHas('designer', fn($q) => $q->where('name', 'ilike', "%{$term}%"));
                });
            }
        }

        // Apply filters with Django parity
        $query = $this->applyFilters($query);

        return $query->orderBy('name');
    }

    /**
     * Apply filters with Django parity
     */
    protected function applyFilters($query)
    {
        return $query
            ->when($this->category, fn($q, $category) =>
                $q->where('ride_type', $category))
            ->when($this->status, fn($q, $status) =>
                $q->where('status', $status))
            ->when($this->manufacturerId, fn($q, $manufacturerId) =>
                $q->where('manufacturer_id', $manufacturerId))
            ->when($this->openingYearFrom, fn($q, $year) =>
                $q->where('opening_date', '>=', "{$year}-01-01"))
            ->when($this->openingYearTo, fn($q, $year) =>
                $q->where('opening_date', '<=', "{$year}-12-31"))
            ->when($this->minHeight, fn($q, $height) =>
                $q->where('height_requirement', '>=', $height))
            ->when($this->maxHeight, fn($q, $height) =>
                $q->where('height_requirement', '<=', $height))
            ->when($this->parkId, fn($q, $parkId) =>
                $q->where('park_id', $parkId));
    }

    /**
     * Get available filter options for dropdowns
     */
    public function getFilterOptionsProperty()
    {
        return $this->remember('filter_options', function () {
            return [
                'categories' => Ride::select('ride_type')
                    ->distinct()
                    ->whereNotNull('ride_type')
                    ->orderBy('ride_type')
                    ->pluck('ride_type', 'ride_type'),
                'statuses' => Ride::select('status')
                    ->distinct()
                    ->whereNotNull('status')
                    ->orderBy('status')
                    ->pluck('status', 'status'),
                'manufacturers' => \App\Models\Manufacturer::orderBy('name')
                    ->pluck('name', 'id'),
                'parks' => \App\Models\Park::orderBy('name')
                    ->pluck('name', 'id'),
            ];
        }, 3600); // 1 hour cache for filter options
    }

    /**
     * Render the component
     */
    public function render()
    {
        return view('livewire.rides-listing', [
            'rides' => $this->rides,
            'filterOptions' => $this->filterOptions,
        ]);
    }

    /**
     * Get cache key for this component
     */
    protected function getCacheKey(string $suffix = ''): string
    {
        return 'thrillwiki.' . class_basename(static::class) . '.' . $suffix;
    }

    /**
     * Remember data with caching
     */
    protected function remember(string $key, $callback, int $ttl = 3600)
    {
        return Cache::remember($this->getCacheKey($key), $ttl, $callback);
    }

    /**
     * Invalidate component cache
     */
    protected function invalidateCache(string $key = null): void
    {
        if ($key) {
            Cache::forget($this->getCacheKey($key));
        } else {
            // Clear all cache for this component
            Cache::flush();
        }
    }
}