<?php

namespace App\Livewire;

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

class DesignersListingUniversal extends Component
{
    use WithPagination;

    // Universal Listing System Integration
    public string $entityType = 'designers';

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

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

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

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

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

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

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

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

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

    #[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 $portfolioStats = [];
    public array $innovationTimeline = [];
    public array $collaborationNetworks = [];

    protected $queryString = [
        'search' => ['except' => ''],
        'specialties' => ['except' => []],
        'designStyle' => ['except' => ''],
        'foundedYearFrom' => ['except' => ''],
        'foundedYearTo' => ['except' => ''],
        'minInnovationScore' => ['except' => ''],
        'maxInnovationScore' => ['except' => ''],
        'minActiveYears' => ['except' => ''],
        'maxActiveYears' => ['except' => ''],
        'sortBy' => ['except' => 'name'],
        'sortDirection' => ['except' => 'asc'],
        'viewMode' => ['except' => 'grid'],
        'page' => ['except' => 1],
    ];

    /**
     * Component initialization
     */
    public function mount(): void
    {
        $this->loadPortfolioStatistics();
        $this->loadInnovationTimeline();
        $this->loadCollaborationNetworks();
    }

    /**
     * Load creative portfolio statistics with caching
     */
    protected function loadPortfolioStatistics(): void
    {
        $this->portfolioStats = Cache::remember(
            'designers.portfolio.stats',
            now()->addHours(6),
            fn() => $this->calculatePortfolioStatistics()
        );
    }

    /**
     * Load innovation timeline data with caching
     */
    protected function loadInnovationTimeline(): void
    {
        $this->innovationTimeline = Cache::remember(
            'designers.innovation.timeline',
            now()->addHours(12),
            fn() => $this->calculateInnovationTimeline()
        );
    }

    /**
     * Load collaboration networks with caching
     */
    protected function loadCollaborationNetworks(): void
    {
        $this->collaborationNetworks = Cache::remember(
            'designers.collaboration.networks',
            now()->addHours(6),
            fn() => $this->calculateCollaborationNetworks()
        );
    }

    /**
     * Calculate comprehensive portfolio statistics
     */
    protected function calculatePortfolioStatistics(): array
    {
        return [
            'total_designers' => Designer::active()->count(),
            'coaster_designers' => Designer::active()->specialty('roller_coaster')->count(),
            'dark_ride_designers' => Designer::active()->specialty('dark_ride')->count(),
            'themed_experience_designers' => Designer::active()->specialty('themed_experience')->count(),
            'water_attraction_designers' => Designer::active()->specialty('water_attraction')->count(),
            'specialties_distribution' => Designer::active()
                ->select('specialty', DB::raw('count(*) as count'))
                ->whereNotNull('specialty')
                ->groupBy('specialty')
                ->orderByDesc('count')
                ->get()
                ->pluck('count', 'specialty')
                ->toArray(),
            'average_innovation_score' => Designer::active()
                ->whereNotNull('innovation_score')
                ->avg('innovation_score'),
            'total_designs' => Designer::active()
                ->withCount('rides')
                ->get()
                ->sum('rides_count'),
            'top_innovators' => Designer::active()
                ->orderByDesc('innovation_score')
                ->take(5)
                ->get(['name', 'innovation_score', 'specialty'])
                ->toArray(),
            'design_styles' => Designer::active()
                ->select('design_style', DB::raw('count(*) as count'))
                ->whereNotNull('design_style')
                ->groupBy('design_style')
                ->orderByDesc('count')
                ->get()
                ->pluck('count', 'design_style')
                ->toArray(),
        ];
    }

    /**
     * Calculate innovation timeline data
     */
    protected function calculateInnovationTimeline(): array
    {
        $timelineData = Designer::active()
            ->whereNotNull('founded_year')
            ->whereNotNull('innovation_score')
            ->select('founded_year', 'innovation_score', 'name', 'specialty')
            ->orderBy('founded_year')
            ->get()
            ->groupBy(function($designer) {
                return floor($designer->founded_year / 10) * 10; // Group by decade
            })
            ->map(function($decade) {
                return [
                    'count' => $decade->count(),
                    'avg_innovation' => $decade->avg('innovation_score'),
                    'top_designer' => $decade->sortByDesc('innovation_score')->first(),
                    'specialties' => $decade->countBy('specialty')->toArray()
                ];
            });

        return [
            'timeline' => $timelineData->toArray(),
            'innovation_milestones' => Designer::active()
                ->where('innovation_score', '>=', 8.5)
                ->orderByDesc('innovation_score')
                ->take(10)
                ->get(['name', 'founded_year', 'innovation_score', 'specialty'])
                ->toArray(),
            'breakthrough_years' => Designer::active()
                ->whereNotNull('founded_year')
                ->select('founded_year', DB::raw('count(*) as new_designers'), DB::raw('avg(innovation_score) as avg_innovation'))
                ->groupBy('founded_year')
                ->having('new_designers', '>=', 2)
                ->orderByDesc('avg_innovation')
                ->take(5)
                ->get()
                ->toArray(),
        ];
    }

    /**
     * Calculate collaboration networks
     */
    protected function calculateCollaborationNetworks(): array
    {
        return [
            'collaboration_pairs' => Designer::active()
                ->whereHas('rides', function($query) {
                    $query->whereHas('park', function($parkQuery) {
                        $parkQuery->whereHas('rides', function($rideQuery) {
                            $rideQuery->whereNotNull('designer_id');
                        });
                    });
                })
                ->with(['rides.park.rides.designer'])
                ->get()
                ->flatMap(function($designer) {
                    return $designer->rides->flatMap(function($ride) use ($designer) {
                        return $ride->park->rides
                            ->where('designer_id', '!=', $designer->id)
                            ->whereNotNull('designer_id')
                            ->pluck('designer.name')
                            ->map(function($collaborator) use ($designer, $ride) {
                                return [
                                    'designer' => $designer->name,
                                    'collaborator' => $collaborator,
                                    'park' => $ride->park->name
                                ];
                            });
                    });
                })
                ->groupBy(function($item) {
                    $names = [$item['designer'], $item['collaborator']];
                    sort($names);
                    return implode(' + ', $names);
                })
                ->map(function($collaborations) {
                    return [
                        'count' => $collaborations->count(),
                        'parks' => $collaborations->pluck('park')->unique()->values()->toArray()
                    ];
                })
                ->sortByDesc('count')
                ->take(10)
                ->toArray(),
            'network_hubs' => Designer::active()
                ->withCount('rides')
                ->having('rides_count', '>=', 3)
                ->orderByDesc('rides_count')
                ->take(10)
                ->get(['name', 'specialty', 'rides_count'])
                ->toArray(),
            'cross_specialty_projects' => Designer::active()
                ->whereHas('rides', function($query) {
                    $query->whereHas('park', function($parkQuery) {
                        $parkQuery->whereHas('rides', function($rideQuery) {
                            $rideQuery->whereHas('designer', function($designerQuery) {
                                $designerQuery->whereColumn('specialty', '!=', 'designers.specialty');
                            });
                        });
                    });
                })
                ->with(['rides.park'])
                ->get()
                ->flatMap(function($designer) {
                    return $designer->rides->map(function($ride) use ($designer) {
                        return [
                            'designer' => $designer->name,
                            'specialty' => $designer->specialty,
                            'park' => $ride->park->name,
                            'ride' => $ride->name
                        ];
                    });
                })
                ->take(15)
                ->toArray(),
        ];
    }

    /**
     * Django parity creative portfolio search functionality
     */
    public function creativePortfolioSearch($query, $specialties = [])
    {
        return Designer::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('specialty', 'ilike', "%{$term}%")
                                    ->orWhere('design_style', 'ilike', "%{$term}%")
                                    ->orWhere('headquarters', 'ilike', "%{$term}%")
                                    ->orWhereHas('rides', function($rideQuery) use ($term) {
                                        $rideQuery->where('name', 'ilike', "%{$term}%")
                                                 ->orWhere('category', 'ilike', "%{$term}%");
                                    })
                                    ->orWhereHas('rides.park', function($parkQuery) use ($term) {
                                        $parkQuery->where('name', 'ilike', "%{$term}%");
                                    });
                        });
                    }
                }
            })
            ->when($specialties, function ($q) use ($specialties) {
                $q->whereIn('specialty', $specialties);
            })
            ->active()
            ->with(['rides:id,designer_id,name,category,park_id', 'rides.park:id,name'])
            ->withCount(['rides']);
    }

    /**
     * Apply creative and innovation filters
     */
    public function applyCreativeFilters($query)
    {
        return $query
            ->when($this->designStyle, fn($q, $style) => 
                $q->where('design_style', $style))
            ->when($this->foundedYearFrom, fn($q, $year) => 
                $q->where('founded_year', '>=', $year))
            ->when($this->foundedYearTo, fn($q, $year) => 
                $q->where('founded_year', '<=', $year))
            ->when($this->minInnovationScore, fn($q, $score) => 
                $q->where('innovation_score', '>=', $score))
            ->when($this->maxInnovationScore, fn($q, $score) => 
                $q->where('innovation_score', '<=', $score))
            ->when($this->minActiveYears, fn($q, $years) => 
                $q->where('active_years', '>=', $years))
            ->when($this->maxActiveYears, fn($q, $years) => 
                $q->where('active_years', '<=', $years));
    }

    /**
     * Get designers with optimized caching
     */
    public function getDesignersProperty()
    {
        $cacheKey = "designers.listing." . md5(serialize([
            'search' => $this->search,
            'specialties' => $this->specialties,
            'designStyle' => $this->designStyle,
            'foundedYearFrom' => $this->foundedYearFrom,
            'foundedYearTo' => $this->foundedYearTo,
            'minInnovationScore' => $this->minInnovationScore,
            'maxInnovationScore' => $this->maxInnovationScore,
            'minActiveYears' => $this->minActiveYears,
            'maxActiveYears' => $this->maxActiveYears,
            'sortBy' => $this->sortBy,
            'sortDirection' => $this->sortDirection,
            'page' => $this->getPage(),
            'perPage' => $this->perPage,
        ]));

        return Cache::remember($cacheKey, now()->addMinutes(30), function() {
            $query = $this->creativePortfolioSearch($this->search, $this->specialties);
            $query = $this->applyCreativeFilters($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 'innovation_score':
                    $query->orderBy('innovation_score', $this->sortDirection);
                    break;
                case 'designed_rides_count':
                    $query->orderBy('rides_count', $this->sortDirection);
                    break;
                case 'active_years':
                    $query->orderBy('active_years', $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 specialties filter and reset pagination
     */
    public function updatedSpecialties(): void
    {
        $this->resetPage();
        $this->invalidateCache();
    }

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

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

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

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

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

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

    public function updatedMaxActiveYears(): 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->specialties = [];
        $this->designStyle = '';
        $this->foundedYearFrom = '';
        $this->foundedYearTo = '';
        $this->minInnovationScore = '';
        $this->maxInnovationScore = '';
        $this->minActiveYears = '';
        $this->maxActiveYears = '';
        $this->sortBy = 'name';
        $this->sortDirection = 'asc';
        
        $this->resetPage();
        $this->invalidateCache();
    }

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

    /**
     * Invalidate component cache
     */
    protected function invalidateCache(): void
    {
        Cache::forget('designers.portfolio.stats');
        Cache::forget('designers.innovation.timeline');
        Cache::forget('designers.collaboration.networks');
        
        // Clear listing cache pattern - simplified approach
        $cacheKeys = [
            'designers.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.designers-listing-universal', [
            'designers' => $this->designers,
            'portfolioStats' => $this->portfolioStats,
            'innovationTimeline' => $this->innovationTimeline,
            'collaborationNetworks' => $this->collaborationNetworks,
        ]);
    }
}