<?php

namespace App\Http\Controllers\Frontend;

use App\Http\Controllers\Controller;
use App\Models\Anime;
use App\Models\AnimeSwipe;
use App\Models\Genre;
use App\Models\Watchlist;
use App\Services\DeepSeekService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class DiscoverController extends Controller
{
    public function index()
    {
        $genres = Genre::where('is_active', true)->orderBy('name')->get(['id', 'name', 'slug']);
        return view('frontend.discover', compact('genres'));
    }

    public function cards(Request $request)
    {
        $genreSlug = $request->input('genre', '');
        $type      = $request->input('type', '');
        $limit     = min((int) $request->input('limit', 10), 10);

        // Auth state'i al
        $isAuth = auth()->check();
        $uid    = $isAuth ? auth()->id() : null;

        try {
            $idQuery = Anime::where('is_published', true)->select('id');

            if ($genreSlug) {
                $idQuery->whereHas('genres', fn($q) => $q->where('slug', $genreSlug));
            }
            if ($type) {
                $idQuery->where('type', $type);
            }

            if ($isAuth && $uid) {
                $exclude = AnimeSwipe::where('user_id', $uid)->pluck('anime_id')
                    ->merge(Watchlist::where('user_id', $uid)->pluck('anime_id'))
                    ->unique();
                if ($exclude->isNotEmpty()) {
                    $idQuery->whereNotIn('id', $exclude);
                }
            }

            $ids = $idQuery->pluck('id');
            if ($ids->isEmpty()) {
                return response()->json(['cards' => [], 'has_more' => false]);
            }

            $randomIds = $ids->shuffle()->take($limit);

            $animes = Anime::whereIn('id', $randomIds)
                ->with('genres:id,name')
                ->get()
                ->shuffle();

            $cards = $animes->map(function (Anime $anime) {
                $hook = $anime->discovery_hook
                    ?: ($anime->description ? Str::limit(strip_tags($anime->description), 130) : null);

                return [
                    'id'            => $anime->id,
                    'slug'          => $anime->slug,
                    'title'         => $anime->title,
                    'cover_url'     => $anime->coverUrl,
                    'banner_url'    => $anime->bannerUrl,
                    'rating'        => $anime->rating ? number_format($anime->rating, 1) : null,
                    'year'          => $anime->release_year,
                    'type'          => $anime->type,
                    'status'        => $anime->status,
                    'episode_count' => $anime->episode_count,
                    'genres'        => $anime->genres->take(3)->pluck('name')->values(),
                    'hook'          => $hook,
                    'description'   => $anime->description ? Str::limit(strip_tags($anime->description), 420) : null,
                ];
            });

            return response()->json([
                'cards'    => $cards,
                'has_more' => $animes->count() === $limit,
            ]);

        } catch (\Exception $e) {
            \Log::error('Discover cards error: ' . $e->getMessage());
            return response()->json(['cards' => [], 'has_more' => false, 'error' => true]);
        }
    }

    public function swipe(Request $request)
    {
        $data = $request->validate([
            'anime_id'  => 'required|integer|exists:animes,id',
            'direction' => 'required|in:like,skip',
        ]);

        if (auth()->check()) {
            $uid = auth()->id();
            AnimeSwipe::updateOrCreate(
                ['user_id' => $uid, 'anime_id' => $data['anime_id']],
                ['direction' => $data['direction']]
            );

            if ($data['direction'] === 'like') {
                Watchlist::updateOrCreate(
                    ['user_id' => $uid, 'anime_id' => $data['anime_id']],
                    ['status' => 'plan']
                );
            }
        } else {
            $seen   = session('guest_swipes', []);
            $seen[] = $data['anime_id'];
            session(['guest_swipes' => array_unique(array_slice($seen, -150))]);
        }

        return response()->json(['ok' => true]);
    }

    public function reset()
    {
        if (auth()->check()) {
            AnimeSwipe::where('user_id', auth()->id())->delete();
        } else {
            session()->forget('guest_swipes');
        }
        return response()->json(['ok' => true]);
    }

    public function results(Request $request)
    {
        // Beğenilen animeler
        if (auth()->check()) {
            $uid      = auth()->id();
            $swipes   = AnimeSwipe::where('user_id', $uid)
                ->with('anime:id,title,slug,cover_image,rating,release_year,type')
                ->orderByDesc('created_at')
                ->get()->filter(fn($s) => $s->anime);

            $likedAnimes = $swipes->where('direction', 'like')
                ->map(fn($s) => $s->anime)
                ->values();

            $allSwipedIds = $swipes->pluck('anime_id');
            $likeCount  = $swipes->where('direction', 'like')->count();
            $skipCount  = $swipes->where('direction', 'skip')->count();
        } else {
            $seen        = session('guest_swipes', []);
            $likedAnimes = collect();
            $allSwipedIds= collect($seen);
            $likeCount   = 0;
            $skipCount   = count($seen);
        }

        // AI önerileri — beğenilen animelerin türlerine benzer, henüz görülmemiş
        $recommendations = collect();
        if ($likedAnimes->isNotEmpty()) {
            $ai = app(DeepSeekService::class);

            // Beğenilen animelerin genre'larını topla
            $likedWithGenres = Anime::whereIn('id', $likedAnimes->pluck('id'))
                ->with('genres:id,name')
                ->get();
            $genreIds = $likedWithGenres->flatMap(fn($a) => $a->genres->pluck('id'))->unique();

            // Benzer ama henüz görülmemiş animeler al — ID shuffle ile ORDER BY RAND() önlenir
            $candidateIds = Anime::where('is_published', true)
                ->whereNotIn('id', $allSwipedIds)
                ->whereHas('genres', fn($q) => $q->whereIn('id', $genreIds))
                ->pluck('id')
                ->shuffle()
                ->take(30);

            $candidateAnimes = Anime::whereIn('id', $candidateIds)
                ->with('genres:id,name')
                ->withCount('episodes')
                ->get()
                ->shuffle();

            if ($ai->isConfigured() && $candidateAnimes->isNotEmpty()) {
                $likedTitles = $likedAnimes->pluck('title')->take(5)->join(', ');
                $preferences = "Kullanıcının beğendiği animeler: {$likedTitles}. Bunlara benzer, aynı türde ya da aynı atmosferde animeler öner.";

                $candidateData = $candidateAnimes->map(fn($a) => [
                    'id'           => $a->id,
                    'title'        => $a->title,
                    'type'         => $a->type,
                    'release_year' => $a->release_year,
                    'rating'       => $a->rating,
                    'genres'       => $a->genres->map(fn($g) => ['name' => $g->name])->toArray(),
                ])->values()->toArray();

                $aiRecs = Cache::remember(
                    'dsc_recs_' . md5($likedAnimes->pluck('id')->sort()->join(',')),
                    60 * 60 * 6,
                    fn() => $ai->recommend($preferences, $candidateData)
                );

                if ($aiRecs) {
                    $recIds = collect($aiRecs)->pluck('id')->map('intval');
                    $recAnimes = $candidateAnimes->whereIn('id', $recIds)->keyBy('id');

                    $recommendations = collect($aiRecs)->take(6)->map(function ($rec) use ($recAnimes) {
                        $anime = $recAnimes->get((int)$rec['id']);
                        if (!$anime) return null;
                        return [
                            'id'        => $anime->id,
                            'slug'      => $anime->slug,
                            'title'     => $anime->title,
                            'cover_url' => $anime->coverUrl,
                            'rating'    => $anime->rating ? number_format($anime->rating, 1) : null,
                            'year'      => $anime->release_year,
                            'genres'    => $anime->genres->take(2)->pluck('name')->values(),
                            'reason'    => $rec['reason'] ?? null,
                        ];
                    })->filter()->values();
                }
            }

            // AI yoksa genre-based fallback
            if ($recommendations->isEmpty()) {
                $recommendations = $candidateAnimes->take(6)->map(fn($a) => [
                    'id'        => $a->id,
                    'slug'      => $a->slug,
                    'title'     => $a->title,
                    'cover_url' => $a->coverUrl,
                    'rating'    => $a->rating ? number_format($a->rating, 1) : null,
                    'year'      => $a->release_year,
                    'genres'    => $a->genres->take(2)->pluck('name')->values(),
                    'reason'    => null,
                ])->values();
            }
        }

        return response()->json([
            'liked'           => $likedAnimes->map(fn($a) => [
                'id'        => $a->id,
                'slug'      => $a->slug,
                'title'     => $a->title,
                'cover_url' => $a->coverUrl,
            ])->values(),
            'recommendations' => $recommendations,
            'like_count'      => $likeCount,
            'skip_count'      => $skipCount,
            'is_auth'         => auth()->check(),
        ]);
    }
}
