<?php

namespace App\Livewire;

use App\Models\Ride;
use App\Models\Park;
use App\Models\Operator;
use Livewire\Component;
use Livewire\Attributes\On;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Collection;

class RidesSearchSuggestions extends Component
{
    public string $query = '';
    public bool $showSuggestions = false;
    public int $maxSuggestions = 8;
    public array $suggestions = [];

    /**
     * Component initialization
     */
    public function mount(string $query = ''): void
    {
        $this->query = $query;
        if (!empty($query)) {
            $this->updateSuggestions();
        }
    }

    /**
     * Listen for search query updates from parent components
     */
    #[On('search-query-updated')]
    public function handleSearchUpdate(string $query): void
    {
        $this->query = $query;
        $this->updateSuggestions();
    }

    /**
     * Update search suggestions based on current query
     */
    public function updateSuggestions(): void
    {
        if (strlen($this->query) < 2) {
            $this->suggestions = [];
            $this->showSuggestions = false;
            return;
        }

        $this->suggestions = $this->remember(
            'suggestions.' . md5(strtolower($this->query)),
            fn() => $this->buildSuggestions(),
            300 // 5-minute cache for suggestions
        );

        $this->showSuggestions = !empty($this->suggestions);
    }

    /**
     * Build search suggestions from multiple sources
     */
    protected function buildSuggestions(): array
    {
        $query = strtolower(trim($this->query));
        $suggestions = collect();

        // Ride name suggestions
        $rideSuggestions = Ride::select('name', 'slug', 'id')
            ->with(['park:id,name,slug'])
            ->where('name', 'ilike', "%{$query}%")
            ->limit(4)
            ->get()
            ->map(function ($ride) {
                return [
                    'type' => 'ride',
                    'title' => $ride->name,
                    'subtitle' => $ride->park->name ?? 'Unknown Park',
                    'url' => route('rides.show', $ride->slug),
                    'icon' => 'ride',
                    'category' => 'Rides'
                ];
            });

        // Park name suggestions
        $parkSuggestions = Park::select('name', 'slug', 'id')
            ->where('name', 'ilike', "%{$query}%")
            ->limit(3)
            ->get()
            ->map(function ($park) {
                return [
                    'type' => 'park',
                    'title' => $park->name,
                    'subtitle' => 'Theme Park',
                    'url' => route('parks.show', $park->slug),
                    'icon' => 'park',
                    'category' => 'Parks'
                ];
            });

        // Manufacturer/Designer suggestions
        $operatorSuggestions = Operator::select('name', 'slug', 'id')
            ->where('name', 'ilike', "%{$query}%")
            ->limit(2)
            ->get()
            ->map(function ($operator) {
                return [
                    'type' => 'operator',
                    'title' => $operator->name,
                    'subtitle' => 'Manufacturer/Designer',
                    'url' => route('operators.show', $operator->slug),
                    'icon' => 'operator',
                    'category' => 'Companies'
                ];
            });

        // Combine and prioritize suggestions
        $suggestions = $suggestions
            ->concat($rideSuggestions)
            ->concat($parkSuggestions)
            ->concat($operatorSuggestions)
            ->take($this->maxSuggestions);

        return $suggestions->toArray();
    }

    /**
     * Handle suggestion selection
     */
    public function selectSuggestion(array $suggestion): void
    {
        $this->dispatch('suggestion-selected', $suggestion);
        $this->hideSuggestions();
    }

    /**
     * Hide suggestions dropdown
     */
    public function hideSuggestions(): void
    {
        $this->showSuggestions = false;
    }

    /**
     * Show suggestions dropdown
     */
    public function showSuggestionsDropdown(): void
    {
        if (!empty($this->suggestions)) {
            $this->showSuggestions = true;
        }
    }

    /**
     * Handle input focus
     */
    public function onFocus(): void
    {
        $this->showSuggestionsDropdown();
    }

    /**
     * Handle input blur with delay to allow clicks
     */
    public function onBlur(): void
    {
        // Delay hiding to allow suggestion clicks
        $this->dispatch('delayed-hide-suggestions');
    }

    /**
     * Get icon class for suggestion type
     */
    public function getIconClass(string $type): string
    {
        return match($type) {
            'ride' => 'fas fa-roller-coaster',
            'park' => 'fas fa-map-marker-alt',
            'operator' => 'fas fa-industry',
            default => 'fas fa-search'
        };
    }

    /**
     * Render the component
     */
    public function render()
    {
        return view('livewire.rides-search-suggestions');
    }

    /**
     * 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();
        }
    }
}