<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Admin\TrendingController;
use App\Models\Anime;
use App\Models\Banner;
use App\Models\Episode;
use App\Models\Genre;
use App\Models\ContinueWatching;
use App\Models\User;
use App\Support\MediaUrl;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;

class HomeController extends Controller
{
    public function index()
    {
        // ── Cache key: 15 dakikada bir rotasyon ──────────────────────────────
        $rotationSlot = (int) floor(now()->timestamp / 900); // 15 dk = 900 sn

        // ── Latest + Top Rated (cache'li) ────────────────────────────────────
        $latest = cache()->remember("home.latest.{$rotationSlot}", 900, fn() =>
            Anime::where('is_published', true)->latest()->take(20)->get()
        );

        $topRated = cache()->remember("home.toprated.{$rotationSlot}", 900, fn() =>
            Anime::where('is_published', true)->where('rating', '>=', 7)
                ->orderByDesc('rating')->take(14)->get()
        );

        $genres = cache()->remember('home.genres', 3600, fn() =>
            Genre::where('is_active', true)
                ->withCount(['animes' => fn($q) => $q->where('is_published', true)])
                ->orderByDesc('animes_count')
                ->take(16)->get()
        );

        $newEpisodes = cache()->remember("home.newepisodes.{$rotationSlot}", 900, fn() =>
            Episode::with(['anime', 'season'])
                ->where('is_published', true)
                ->latest()->take(14)->get()
        );

        // ── Trending: YouTube-benzeri skor ───────────────────────────────────
        $trending = cache()->remember("home.trending.{$rotationSlot}", 900, function () use ($latest) {
            try {
                // trending_score kolonu varsa kullan (migration çalıştırıldıysa)
                $byScore = Anime::where('is_published', true)
                    ->where(fn($q) => $q->where('trending_score', '>', 0)->orWhere('is_trending', true))
                    ->orderByDesc('trending_score')
                    ->take(12)
                    ->get();

                if ($byScore->count() >= 6) return $byScore;
            } catch (\Throwable) {}

            // Fallback: manuel + view_count bazlı
            $manual = Anime::where('is_trending', true)->where('is_published', true)
                ->orderBy('trending_order')->take(12)->get();
            if ($manual->count() >= 6) return $manual->take(12);

            $autoFill = Anime::where('is_published', true)
                ->whereNotIn('id', $manual->pluck('id'))
                ->withSum(['episodes as recent_views' => fn($q) =>
                    $q->where('is_published', true)->where('updated_at', '>=', now()->subDays(30))
                ], 'view_count')
                ->orderByDesc('recent_views')
                ->take(12 - $manual->count())->get();

            $merged = $manual->concat($autoFill);
            return $merged->isEmpty() ? $latest->take(12) : $merged;
        });

        // Rotasyon: top 8 sabit, son 4 her 15dk'da shuffle
        $top8    = $trending->take(8)->values();
        $bottom4 = $trending->slice(8)->shuffle()->values();
        $trending = $top8->concat($bottom4)->take(12)->values();

        // ── Devam Ediyor (Bu Sezon) ───────────────────────────────────────────
        $ongoing = cache()->remember("home.ongoing.{$rotationSlot}", 900, fn() =>
            Anime::where('is_published', true)->where('status', 'ongoing')
                ->orderByDesc('rating')->take(12)->get()
        );

        // ── Popüler Filmler ───────────────────────────────────────────────────
        $popularMovies = cache()->remember("home.movies.{$rotationSlot}", 900, fn() =>
            Anime::where('is_published', true)->where('type', 'movie')
                ->where('rating', '>=', 6)->orderByDesc('rating')->take(12)->get()
        );

        // ── Türkçe Dublaj ─────────────────────────────────────────────────────
        $dubbed = cache()->remember("home.dubbed.{$rotationSlot}", 900, fn() =>
            Anime::where('is_published', true)->where('is_dubbed', true)
                ->orderByDesc('rating')->take(20)->get()
        );

        // ── Tür Spotlight (2 farklı tür, her birinde top 8 anime) ────────────
        $genreSpotlights = cache()->remember("home.genre_spots.{$rotationSlot}", 900, function () {
            $spotGenres = Genre::where('is_active', true)
                ->whereIn('name', ['Aksiyon', 'Fantezi', 'Romantik', 'Psikolojik', 'Komedi', 'Spor', 'Macera', 'Drama'])
                ->inRandomOrder()->take(3)->get();

            return $spotGenres->map(fn($g) => [
                'genre' => $g,
                'animes' => $g->animes()
                    ->where('is_published', true)
                    ->where('rating', '>=', 6)
                    ->orderByDesc('rating')
                    ->take(8)->get(),
            ])->filter(fn($s) => $s['animes']->count() >= 3)->values();
        });

        // ── Featured Hero Slider: YouTube-benzeri trending algoritması ─────────
        $featured = cache()->remember("home.featured.{$rotationSlot}", 900, function () use ($trending, $topRated, $latest) {
            // trending_score kolonu var mı? (migration çalıştırılmamışsa fallback)
            $hasTrendingScore = \Illuminate\Support\Facades\Schema::hasColumn('animes', 'trending_score');

            $orderBy = fn($q) => $hasTrendingScore
                ? $q->orderByDesc('trending_score')
                : $q->orderByDesc('rating');

            $used = collect();

            // TIER 1: Son 24 saatte yeni bölüm + trend skoru yüksek + banner
            try {
                $tier1Ids = Episode::where('is_published', true)
                    ->where('created_at', '>=', now()->subDay())
                    ->pluck('anime_id')->unique()->toArray();

                $tier1 = $orderBy(Anime::where('is_published', true)
                    ->whereIn('id', $tier1Ids)
                    ->whereNotNull('banner_image'))
                    ->take(6)->get();
                $used = $used->concat($tier1->pluck('id'));
            } catch (\Throwable) {
                $tier1 = collect();
            }

            // TIER 2: Son 3 günde yeni bölüm + banner
            $tier2 = collect();
            if ($tier1->count() < 6) {
                try {
                    $tier2Ids = Episode::where('is_published', true)
                        ->where('created_at', '>=', now()->subDays(3))
                        ->pluck('anime_id')->unique()->diff($used)->toArray();

                    $tier2 = $orderBy(Anime::where('is_published', true)
                        ->whereIn('id', $tier2Ids)
                        ->whereNotNull('banner_image'))
                        ->take(6 - $tier1->count())->get();
                    $used = $used->concat($tier2->pluck('id'));
                } catch (\Throwable) {}
            }

            $combined = $tier1->concat($tier2);

            // TIER 3: Yüksek skor + banner
            if ($combined->count() < 6) {
                try {
                    $tier3 = $orderBy(Anime::where('is_published', true)
                        ->whereNotIn('id', $used->toArray())
                        ->whereNotNull('banner_image'))
                        ->take(6 - $combined->count())->get();
                    $used = $used->concat($tier3->pluck('id'));
                    $combined = $combined->concat($tier3);
                } catch (\Throwable) {}
            }

            // TIER 4: Trending + topRated (banner olmadan)
            if ($combined->count() < 5) {
                $fill = $trending->whereNotIn('id', $used->toArray())->take(5 - $combined->count());
                $combined = $combined->concat($fill);
            }
            if ($combined->count() < 5) {
                $fill2 = $topRated->whereNotIn('id', $combined->pluck('id'))->take(5 - $combined->count());
                $combined = $combined->concat($fill2);
            }

            return $combined->isEmpty() ? $latest->take(5)->values() : $combined->values();
        });

        $featured->load('genres', 'seasons', 'episodes');

        // ── Hero slider JSON ──────────────────────────────────────────────────
        $statusLabel = ['ongoing' => 'Devam Ediyor', 'completed' => 'Tamamlandı', 'upcoming' => 'Yakında'];
        $featuredSlider = $featured->values()->map(function ($a) use ($statusLabel) {
            $firstSeason = $a->seasons->sortBy('season_number')->first();
            $firstEp     = $firstSeason
                ? $a->episodes->where('season_id', $firstSeason->id)->where('is_published', true)->sortBy('episode_number')->first()
                : null;
            return [
                'title'       => $a->title,
                'description' => $a->description,
                'rating'      => $a->rating,
                'year'        => $a->release_year,
                'episodes'    => $a->episode_count,
                'status'      => $a->status,
                'statusLabel' => $statusLabel[$a->status] ?? $a->status,
                'slug'        => $a->slug,
                'genres'      => $a->genres->pluck('name')->values(),
                'coverUrl'    => $a->coverUrl,
                'bannerUrl'   => $a->bannerUrl,
                'studio'      => $a->studio,
                'watchUrl'    => ($firstSeason && $firstEp)
                    ? route('watch', [$a->slug, $firstSeason->season_number, $firstEp->episode_number])
                    : null,
                'detailUrl'   => route('anime.show', $a->slug),
            ];
        })->toArray();

        // ── Devam Et (auth) ───────────────────────────────────────────────────
        $continueWatching = collect();
        $recommended      = collect();
        $userWatchTitles  = '';

        if (auth()->check()) {
            try {
                $continueWatching = ContinueWatching::where('user_id', auth()->id())
                    ->with('anime:id,title,slug,cover_image')
                    ->where('percent_complete', '>=', 5)
                    ->where('percent_complete', '<', 95)
                    ->orderByDesc('updated_at')
                    ->limit(12)
                    ->get();

                $watchedIds = ContinueWatching::where('user_id', auth()->id())->pluck('anime_id');

                if ($watchedIds->isNotEmpty()) {
                    $topGenreIds = DB::table('anime_genre')
                        ->whereIn('anime_id', $watchedIds)
                        ->select('genre_id', DB::raw('count(*) as cnt'))
                        ->groupBy('genre_id')
                        ->orderByDesc('cnt')
                        ->limit(5)
                        ->pluck('genre_id');

                    if ($topGenreIds->isNotEmpty()) {
                        $recommended = Anime::where('is_published', true)
                            ->whereNotIn('id', $watchedIds)
                            ->whereHas('genres', fn($q) => $q->whereIn('genres.id', $topGenreIds))
                            ->inRandomOrder()
                            ->take(14)
                            ->get();

                        // Yeterli değilse rating'e göre topRated'dan dolduralım
                        if ($recommended->count() < 6) {
                            $fallback = Anime::where('is_published', true)
                                ->whereNotIn('id', $watchedIds->merge($recommended->pluck('id')))
                                ->where('rating', '>=', 6)
                                ->inRandomOrder()
                                ->take(14 - $recommended->count())
                                ->get();
                            $recommended = $recommended->concat($fallback)->shuffle()->values();
                        }
                    }

                    $userWatchTitles = Anime::whereIn('id', $watchedIds->take(8))
                        ->pluck('title')->join(', ');
                }
            } catch (\Throwable $e) {}
        }

        // ── Stats ─────────────────────────────────────────────────────────────
        $statsAnime   = cache()->remember('home.stats.anime',   3600, fn() => Anime::where('is_published', true)->count());
        $statsEpisode = cache()->remember('home.stats.episode', 3600, fn() => Episode::where('is_published', true)->count());
        $statsUser    = cache()->remember('home.stats.user',    3600, fn() => User::count());
        $statsGenre   = cache()->remember('home.stats.genre',   3600, fn() => Genre::where('is_active', true)->count());

        $apkUrl = \App\Models\Setting::get('mobile_apk_url', '');

        // ── Banner reklamlar (premium görmez) ────────────────────────────────
        $bannerAds = ['home_mid' => null, 'home_bottom' => null];
        if (\App\Models\Setting::get('banner_ads_enabled', '0') === '1'
            && !(auth()->check() && auth()->user()->isPremium())) {
            try {
                $bannerAds['home_mid']    = \App\Models\Ad::pickBanner('home_mid');
                $bannerAds['home_bottom'] = \App\Models\Ad::pickBanner('home_bottom');
            } catch (\Throwable $e) {}
        }

        return view('frontend.home', compact(
            'featured', 'featuredSlider', 'latest', 'topRated', 'genres',
            'newEpisodes', 'trending', 'continueWatching', 'recommended', 'userWatchTitles',
            'statsAnime', 'statsEpisode', 'statsUser', 'statsGenre',
            'ongoing', 'popularMovies', 'genreSpotlights', 'dubbed', 'apkUrl', 'bannerAds'
        ));
    }

    public function search()
    {
        $q      = request('q', '');
        $genre  = request('genre');
        $type   = request('type');
        $status = request('status');
        $year   = request('year');
        $sort   = request('sort', 'popular');

        $query = Anime::where('is_published', true)
            ->whereNotNull('slug')
            ->where('slug', '!=', '');

        if ($q) {
            $query->where(function ($qb) use ($q) {
                $qb->where('title', 'like', "%$q%")
                   ->orWhere('title_en', 'like', "%$q%")
                   ->orWhere('title_jp', 'like', "%$q%");
            });
        }
        if ($genre) {
            $query->whereHas('genres', fn($qb) => $qb->where('slug', $genre));
        }
        if ($type) {
            $query->where('type', $type);
        }
        if ($status) {
            $query->where('status', $status);
        }
        if ($year) {
            $query->where('release_year', $year);
        }

        // JSON autocomplete modu
        if (request()->boolean('json') || request()->expectsJson()) {
            $animes = $query->select('id', 'title', 'title_en', 'cover_image', 'type')
                ->latest()->limit(8)->get()
                ->map(fn($a) => [
                    'id'    => $a->id,
                    'title' => $a->title,
                    'cover' => $a->coverUrl,
                    'type'  => $a->type,
                ]);
            return response()->json(['animes' => $animes]);
        }

        // ── Sıralama ──────────────────────────────────────────────────────────
        switch ($sort) {
            case 'popular':
                $query->withSum(['episodes as total_views' => fn($q) =>
                    $q->where('is_published', true)
                ], 'view_count')->orderByDesc('total_views');
                break;

            case 'rating':
                $query->orderByDesc('rating')->orderByDesc('created_at');
                break;

            case 'newest':
                $query->orderByDesc('release_year')->orderByDesc('created_at');
                break;

            case 'oldest':
                $query->orderBy('release_year')->orderBy('created_at');
                break;

            case 'az':
                $query->orderBy('title');
                break;

            case 'za':
                $query->orderByDesc('title');
                break;

            case 'personalized':
                if (auth()->check()) {
                    $watchedIds = \App\Models\ContinueWatching::where('user_id', auth()->id())
                        ->pluck('anime_id');

                    $topGenreIds = $watchedIds->isNotEmpty()
                        ? DB::table('anime_genre')
                            ->whereIn('anime_id', $watchedIds)
                            ->select('genre_id', DB::raw('count(*) as cnt'))
                            ->groupBy('genre_id')
                            ->orderByDesc('cnt')
                            ->limit(6)
                            ->pluck('genre_id')
                        : collect();

                    if ($topGenreIds->isNotEmpty()) {
                        $matchingIds = DB::table('anime_genre')
                            ->whereIn('genre_id', $topGenreIds)
                            ->pluck('anime_id')
                            ->unique()
                            ->values();

                        $idList = $matchingIds->isEmpty() ? '0' : $matchingIds->join(',');
                        $query->orderByRaw("CASE WHEN animes.id IN ($idList) THEN 0 ELSE 1 END")
                              ->orderByDesc('rating');
                    } else {
                        $query->orderByDesc('rating');
                    }
                } else {
                    $query->orderByDesc('rating');
                }
                break;

            default:
                $query->orderByDesc('created_at');
        }

        $results = $query->paginate(24)->withQueryString();
        $genres  = Genre::where('is_active', true)->get();
        $years   = Anime::where('is_published', true)->whereNotNull('release_year')
                        ->distinct()->orderByDesc('release_year')->pluck('release_year');

        return view('frontend.search', compact(
            'results', 'genres', 'years', 'q', 'genre', 'type', 'status', 'year', 'sort'
        ));
    }

    public function searchSuggest()
    {
        $q = trim(request('q', ''));
        if (strlen($q) < 2) {
            return response()->json(['results' => []]);
        }
        $animes = Anime::where('is_published', true)
            ->where(function ($qb) use ($q) {
                $qb->where('title', 'like', "%$q%")
                   ->orWhere('title_en', 'like', "%$q%")
                   ->orWhere('title_jp', 'like', "%$q%");
            })
            ->select('id', 'title', 'title_en', 'slug', 'cover_image', 'type', 'release_year', 'episode_count')
            ->orderByRaw("CASE WHEN title LIKE ? THEN 0 ELSE 1 END, title ASC", ["$q%"])
            ->limit(7)
            ->get()
            ->map(fn($a) => [
                'title'    => $a->title,
                'title_en' => $a->title_en,
                'slug'     => $a->slug,
                'cover'    => $a->coverUrl,
                'type'     => $a->type,
                'year'     => $a->release_year,
                'episodes' => $a->episode_count,
            ]);

        return response()->json(['results' => $animes]);
    }

    public function genre(Genre $genre)
    {
        $animes = $genre->animes()->where('is_published', true)->latest()->paginate(24);
        return view('frontend.genre', compact('genre', 'animes'));
    }
}
