<?php

namespace App\Livewire;

use App\Models\Park;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithPagination;

class SearchComponent extends Component
{
    use WithPagination;

    // Filter properties
    public string $search = '';
    public string $location = '';
    public ?float $minRating = null;
    public ?float $maxRating = null;
    public ?int $minRides = null;
    public ?int $minCoasters = null;
    public bool $filtersApplied = false;

    // Querystring parameters
    protected $queryString = [
        'search' => ['except' => ''],
        'location' => ['except' => ''],
        'minRating' => ['except' => ''],
        'maxRating' => ['except' => ''],
        'minRides' => ['except' => ''],
        'minCoasters' => ['except' => '']
    ];

    public function mount(): void
    {
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function render(): View
    {
        return view('livewire.search', [
            'results' => $this->getFilteredParks()
        ]);
    }

    public function updatedSearch(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    #[On('suggestion-selected')]
    public function handleSuggestionSelected($id, $text): void
    {
        $park = Park::find($id);
        if ($park) {
            $this->search = $text;
            $this->filtersApplied = $this->hasActiveFilters();
            redirect()->route('parks.show', $park);
        }
    }

    public function updatedLocation(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function updatedMinRating(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function updatedMaxRating(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function updatedMinRides(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function updatedMinCoasters(): void
    {
        $this->resetPage();
        $this->filtersApplied = $this->hasActiveFilters();
    }

    public function clearFilters(): void
    {
        $this->reset([
            'search',
            'location',
            'minRating',
            'maxRating',
            'minRides',
            'minCoasters'
        ]);
        $this->filtersApplied = false;
        $this->resetPage();
    }

    protected function getFilteredParks()
    {
        return Park::query()
            ->select('parks.*')
            ->with(['location', 'photos'])
            ->when($this->search, function (Builder $query) {
                $query->where(function (Builder $query) {
                    $query->where('name', 'like', "%{$this->search}%")
                        ->orWhere('description', 'like', "%{$this->search}%");
                });
            })
            ->when($this->location, function (Builder $query) {
                $query->whereHas('location', function (Builder $query) {
                    $query->where('address_text', 'like', "%{$this->location}%");
                });
            })
            ->when($this->minRating, function (Builder $query) {
                $query->where('average_rating', '>=', $this->minRating);
            })
            ->when($this->maxRating, function (Builder $query) {
                $query->where('average_rating', '<=', $this->maxRating);
            })
            ->when($this->minRides, function (Builder $query) {
                $query->where('ride_count', '>=', $this->minRides);
            })
            ->when($this->minCoasters, function (Builder $query) {
                $query->where('coaster_count', '>=', $this->minCoasters);
            })
            ->paginate(10);
    }

    protected function hasActiveFilters(): bool
    {
        return !empty($this->search)
            || !empty($this->location)
            || !empty($this->minRating)
            || !empty($this->maxRating)
            || !empty($this->minRides)
            || !empty($this->minCoasters);
    }
}