<?php

namespace App\Livewire;

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

class OperatorsListing extends Component
{
    use WithPagination;

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

    #[Url(as: 'roles')]
    public array $roleFilter = [];

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

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

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

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

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

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

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

    #[Url(as: 'sort')]
    public string $sortBy = 'name';

    #[Url(as: 'dir')]
    public string $sortDirection = 'asc';

    #[Url(as: 'view')]
    public string $viewMode = 'grid';

    public int $perPage = 20;
    public array $industryStats = [];
    public array $marketData = [];

    protected $queryString = [
        'search' => ['except' => ''],
        'roleFilter' => ['except' => []],
        'industrySector' => ['except' => ''],
        'companySize' => ['except' => ''],
        'foundedYearFrom' => ['except' => ''],
        'foundedYearTo' => ['except' => ''],
        'geographicPresence' => ['except' => ''],
        'minRevenue' => ['except' => ''],
        'maxRevenue' => ['except' => ''],
        'sortBy' => ['except' => 'name'],
        'sortDirection' => ['except' => 'asc'],
        'viewMode' => ['except' => 'grid'],
        'page' => ['except' => 1],
    ];

    /**
     * Component initialization
     */
    public function mount(): void
    {
        $this->loadIndustryStatistics();
        $this->loadMarketData();
    }

    /**
     * Load industry statistics with caching
     */
    protected function loadIndustryStatistics(): void
    {
        $this->industryStats = Cache::remember(
            'operators.industry.stats',
            now()->addHours(6),
            fn() => $this->calculateIndustryStatistics()
        );
    }

    /**
     * Load market analysis data with caching
     */
    protected function loadMarketData(): void
    {
        $this->marketData = Cache::remember(
            'operators.market.data',
            now()->addHours(12),
            fn() => $this->loadMarketAnalysis()
        );
    }

    /**
     * Calculate comprehensive industry statistics
     */
    protected function calculateIndustryStatistics(): array
    {
        return [
            'total_operators' => Operator::active()->count(),
            'park_operators' => Operator::active()->parkOperators()->count(),
            'manufacturers' => Operator::active()->manufacturers()->count(),
            'designers' => Operator::active()->designers()->count(),
            'mixed_role' => Operator::active()
                ->whereHas('parks')
                ->whereHas('manufactured_rides')
                ->count(),
            'sectors' => Operator::active()
                ->select('industry_sector', DB::raw('count(*) as count'))
                ->whereNotNull('industry_sector')
                ->groupBy('industry_sector')
                ->orderByDesc('count')
                ->get()
                ->pluck('count', 'industry_sector')
                ->toArray(),
            'company_sizes' => [
                'small' => Operator::active()->companySize('small')->count(),
                'medium' => Operator::active()->companySize('medium')->count(),
                'large' => Operator::active()->companySize('large')->count(),
                'enterprise' => Operator::active()->companySize('enterprise')->count(),
            ],
            'geographic_distribution' => Operator::active()
                ->whereHas('parks.location')
                ->with('parks.location')
                ->get()
                ->flatMap(fn($op) => $op->parks->pluck('location.country'))
                ->countBy()
                ->sortDesc()
                ->take(10)
                ->toArray(),
        ];
    }

    /**
     * Load market analysis data
     */
    protected function loadMarketAnalysis(): array
    {
        return [
            'total_market_cap' => Operator::active()
                ->whereNotNull('market_cap')
                ->sum('market_cap'),
            'total_revenue' => Operator::active()
                ->whereNotNull('annual_revenue')
                ->sum('annual_revenue'),
            'average_parks_per_operator' => Operator::active()
                ->parkOperators()
                ->avg('total_parks'),
            'top_operators_by_parks' => Operator::active()
                ->parkOperators()
                ->orderByDesc('total_parks')
                ->take(5)
                ->get(['name', 'total_parks'])
                ->toArray(),
            'top_manufacturers_by_rides' => Operator::active()
                ->manufacturers()
                ->orderByDesc('total_rides_manufactured')
                ->take(5)
                ->get(['name', 'total_rides_manufactured'])
                ->toArray(),
        ];
    }

    /**
     * Django parity dual-role search functionality
     */
    public function dualRoleSearch($query, $roles = [])
    {
        return Operator::query()
            ->when($query, function ($q) use ($query) {
                $terms = explode(' ', trim($query));
                foreach ($terms as $term) {
                    if (strlen($term) >= 2) {
                        $q->where(function ($subQuery) use ($term) {
                            $subQuery->where('name', 'ilike', "%{$term}%")
                                    ->orWhere('description', 'ilike', "%{$term}%")
                                    ->orWhere('industry_sector', 'ilike', "%{$term}%")
                                    ->orWhere('headquarters_location', 'ilike', "%{$term}%")
                                    ->orWhereHas('location', function($locQuery) use ($term) {
                                        $locQuery->where('city', 'ilike', "%{$term}%")
                                                ->orWhere('state', 'ilike', "%{$term}%")
                                                ->orWhere('country', 'ilike', "%{$term}%");
                                    });
                        });
                    }
                }
            })
            ->when($roles, function ($q) use ($roles) {
                $q->where(function ($roleQuery) use ($roles) {
                    if (in_array('park_operator', $roles)) {
                        $roleQuery->whereHas('parks');
                    }
                    if (in_array('ride_manufacturer', $roles)) {
                        $roleQuery->orWhereHas('manufactured_rides');
                    }
                    if (in_array('ride_designer', $roles)) {
                        $roleQuery->orWhereHas('designed_rides');
                    }
                });
            })
            ->active()
            ->with(['location', 'parks:id,operator_id,name', 'manufactured_rides:id,manufacturer_id,name', 'designed_rides:id,designer_id,name'])
            ->withCount(['parks', 'manufactured_rides', 'designed_rides']);
    }

    /**
     * Apply advanced industry filters
     */
    public function applyIndustryFilters($query)
    {
        return $query
            ->when($this->industrySector, fn($q, $sector) => 
                $q->where('industry_sector', $sector))
            ->when($this->companySize, fn($q, $size) => 
                $q->companySize($size))
            ->when($this->foundedYearFrom, fn($q, $year) => 
                $q->where('founded_year', '>=', $year))
            ->when($this->foundedYearTo, fn($q, $year) => 
                $q->where('founded_year', '<=', $year))
            ->when($this->geographicPresence, function ($q, $presence) {
                switch ($presence) {
                    case 'regional':
                        $q->whereHas('parks', function ($parkQ) {
                            $parkQ->whereHas('location', function ($locQ) {
                                $locQ->havingRaw('COUNT(DISTINCT country) = 1');
                            });
                        });
                        break;
                    case 'international':
                        $q->whereHas('parks', function ($parkQ) {
                            $parkQ->whereHas('location', function ($locQ) {
                                $locQ->havingRaw('COUNT(DISTINCT country) > 1');
                            });
                        });
                        break;
                }
            })
            ->when($this->minRevenue, fn($q, $revenue) => 
                $q->where('annual_revenue', '>=', $revenue))
            ->when($this->maxRevenue, fn($q, $revenue) => 
                $q->where('annual_revenue', '<=', $revenue));
    }

    /**
     * Get operators with optimized caching
     */
    public function getOperatorsProperty()
    {
        $cacheKey = "operators.listing." . md5(serialize([
            'search' => $this->search,
            'roleFilter' => $this->roleFilter,
            'industrySector' => $this->industrySector,
            'companySize' => $this->companySize,
            'foundedYearFrom' => $this->foundedYearFrom,
            'foundedYearTo' => $this->foundedYearTo,
            'geographicPresence' => $this->geographicPresence,
            'minRevenue' => $this->minRevenue,
            'maxRevenue' => $this->maxRevenue,
            'sortBy' => $this->sortBy,
            'sortDirection' => $this->sortDirection,
            'page' => $this->getPage(),
            'perPage' => $this->perPage,
        ]));

        return Cache::remember($cacheKey, now()->addMinutes(30), function() {
            $query = $this->dualRoleSearch($this->search, $this->roleFilter);
            $query = $this->applyIndustryFilters($query);
            
            // Apply sorting
            switch ($this->sortBy) {
                case 'name':
                    $query->orderBy('name', $this->sortDirection);
                    break;
                case 'founded_year':
                    $query->orderBy('founded_year', $this->sortDirection);
                    break;
                case 'parks_count':
                    $query->orderBy('total_parks', $this->sortDirection);
                    break;
                case 'rides_count':
                    $query->orderBy('total_rides_manufactured', $this->sortDirection);
                    break;
                case 'revenue':
                    $query->orderBy('annual_revenue', $this->sortDirection);
                    break;
                case 'market_influence':
                    $query->orderByRaw('(total_parks * 10 + total_rides_manufactured * 2) ' . $this->sortDirection);
                    break;
                default:
                    $query->orderBy('name', 'asc');
            }

            return $query->paginate($this->perPage);
        });
    }

    /**
     * Update search and reset pagination
     */
    public function updatedSearch(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Update role filter and reset pagination
     */
    public function updatedRoleFilter(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Update any filter and reset pagination
     */
    public function updatedIndustrySector(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedCompanySize(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedFoundedYearFrom(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedFoundedYearTo(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedGeographicPresence(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedMinRevenue(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    public function updatedMaxRevenue(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Sort by specific column
     */
    public function sortBy(string $column): void
    {
        if ($this->sortBy === $column) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortBy = $column;
            $this->sortDirection = 'asc';
        }
        
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Change view mode
     */
    public function setViewMode(string $mode): void
    {
        $this->viewMode = $mode;
    }

    /**
     * Clear all filters
     */
    public function clearFilters(): void
    {
        $this->search = '';
        $this->roleFilter = [];
        $this->industrySector = '';
        $this->companySize = '';
        $this->foundedYearFrom = '';
        $this->foundedYearTo = '';
        $this->geographicPresence = '';
        $this->minRevenue = '';
        $this->maxRevenue = '';
        $this->sortBy = 'name';
        $this->sortDirection = 'asc';
        
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Toggle role filter
     */
    public function toggleRoleFilter(string $role): void
    {
        if (in_array($role, $this->roleFilter)) {
            $this->roleFilter = array_values(array_diff($this->roleFilter, [$role]));
        } else {
            $this->roleFilter[] = $role;
        }
        
        $this->resetPage();
        $this->invalidateCache();
    }

    /**
     * Invalidate component cache
     */
    protected function invalidateCache(): void
    {
        Cache::forget('operators.industry.stats');
        Cache::forget('operators.market.data');
        
        // Clear listing cache pattern - simplified approach
        $cacheKeys = [
            'operators.listing.*'
        ];
        
        foreach ($cacheKeys as $pattern) {
            Cache::forget($pattern);
        }
    }

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

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