<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Anime;
use App\Models\Episode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class TrendingController extends Controller
{
    /**
     * Trend yönetim sayfası.
     */
    public function index()
    {
        $manual = Anime::where('is_trending', true)
            ->where('is_published', true)
            ->orderBy('trending_order')
            ->get();

        $autoTrending = $this->getAutoTrending(20);

        // Son skor hesaplama zamanı
        $lastComputed = cache()->get('trending_score_computed_at');

        return view('admin.trending.index', compact('manual', 'autoTrending', 'lastComputed'));
    }

    // ── Manuel trending yönetimi ──────────────────────────────────────────────

    public function toggle(Request $request, Anime $anime)
    {
        $newState = !$anime->is_trending;

        if ($newState) {
            $maxOrder = Anime::where('is_trending', true)->max('trending_order') ?? 0;
            $anime->update([
                'is_trending'    => true,
                'trending_order' => $maxOrder + 1,
                'trending_score' => $anime->trending_score + 200, // Manuel boost
            ]);
        } else {
            $anime->update(['is_trending' => false, 'trending_order' => 0]);
            $this->reorderAll();
        }

        if ($request->wantsJson()) {
            return response()->json(['ok' => true, 'is_trending' => $newState]);
        }
        return back()->with('success', $newState
            ? '"'.$anime->title.'" trend listesine eklendi.'
            : '"'.$anime->title.'" trend listesinden çıkarıldı.');
    }

    public function reorder(Request $request)
    {
        $request->validate(['ids' => 'required|array', 'ids.*' => 'integer']);
        foreach ($request->ids as $i => $id) {
            Anime::where('id', $id)->update(['trending_order' => $i + 1]);
        }
        return response()->json(['ok' => true]);
    }

    public function move(Request $request, Anime $anime)
    {
        $direction = $request->input('direction');
        $current   = $anime->trending_order;

        if ($direction === 'up' && $current > 1) {
            $swap = Anime::where('is_trending', true)->where('trending_order', $current - 1)->first();
            if ($swap) { $swap->update(['trending_order' => $current]); $anime->update(['trending_order' => $current - 1]); }
        } elseif ($direction === 'down') {
            $swap = Anime::where('is_trending', true)->where('trending_order', $current + 1)->first();
            if ($swap) { $swap->update(['trending_order' => $current]); $anime->update(['trending_order' => $current + 1]); }
        }

        return back();
    }

    public function search(Request $request)
    {
        $results = Anime::where('is_published', true)
            ->where('title', 'like', "%{$request->query('q', '')}%")
            ->select('id', 'title', 'cover_image', 'is_trending', 'release_year', 'trending_score')
            ->take(8)->get()
            ->map(fn($a) => [
                'id'            => $a->id,
                'title'         => $a->title,
                'cover'         => $a->coverUrl,
                'is_trending'   => (bool) $a->is_trending,
                'year'          => $a->release_year,
                'trending_score'=> round($a->trending_score, 1),
            ]);
        return response()->json(['results' => $results]);
    }

    // ── Trend Skoru Hesaplama (YouTube algoritması) ───────────────────────────

    /**
     * Admin butonu: tüm animelerin trend skorunu hesapla ve kaydet.
     * POST /admin/trending/compute-scores
     */
    public function computeScores()
    {
        $count = self::runScoreComputation();
        cache()->put('trending_score_computed_at', now()->toDateTimeString(), 3600);
        cache()->flush(); // Anasayfa cache'ini temizle

        return response()->json([
            'ok'      => true,
            'updated' => $count,
            'message' => "{$count} anime için trend skoru güncellendi.",
        ]);
    }

    /**
     * YouTube-benzeri Trend Skoru Algoritması
     * ─────────────────────────────────────────
     * score = view_24h × 12        ← Son 24 saatin izlenme sayısı (en yüksek ağırlık)
     *       + view_7d  × 4         ← Son 7 günün izlenme sayısı
     *       + view_30d × 1         ← Son 30 günün izlenme sayısı
     *       + watch_minutes_7d × 0.8  ← Gerçek izleme dakikası (kalite sinyali)
     *       + new_episode_bonus    ← Yeni bölüm varsa büyük bonus
     *       + rating × 4           ← Kalite sinyali
     *       + manual_boost         ← Manuel trending = +250
     *
     * Decay: Eski içeriklerin skoru doğal olarak düşer (view_count azalır).
     * Herhangi bir yeni bölüm veya izlenme olmadan skor sıfıra yaklaşır.
     */
    public static function runScoreComputation(): int
    {
        $now     = now();
        $day1    = $now->copy()->subDay();
        $day7    = $now->copy()->subDays(7);
        $day30   = $now->copy()->subDays(30);

        $animes = DB::table('animes')
            ->where('is_published', true)
            ->select('id', 'rating', 'is_trending', 'status')
            ->get();

        $updated = 0;

        foreach ($animes as $anime) {
            // ── Bölüm izlenme sayıları (view_count zaman dilimine göre) ──────
            // Episode.updated_at → son izleme zamanının proxy'si
            $views = DB::table('episodes')
                ->where('anime_id', $anime->id)
                ->where('is_published', true)
                ->selectRaw("
                    SUM(CASE WHEN updated_at >= ? THEN view_count ELSE 0 END) as v24h,
                    SUM(CASE WHEN updated_at >= ? THEN view_count ELSE 0 END) as v7d,
                    SUM(CASE WHEN updated_at >= ? THEN view_count ELSE 0 END) as v30d
                ", [$day1, $day7, $day30])
                ->first();

            // ── Gerçek izleme dakikası (analytics_watch_events) ─────────────
            $watchMinutes = 0;
            try {
                $watchMinutes = DB::table('analytics_watch_events')
                    ->where('anime_id', $anime->id)
                    ->where('created_at', '>=', $day7)
                    ->sum('seconds_watched') / 60;
            } catch (\Throwable) {}

            // ── Yeni bölüm bonusu ────────────────────────────────────────────
            $newEpBonus = 0;
            $latestEpDate = DB::table('episodes')
                ->where('anime_id', $anime->id)
                ->where('is_published', true)
                ->max('created_at');

            if ($latestEpDate) {
                $epAge = now()->diffInHours($latestEpDate);
                if ($epAge <= 24)  $newEpBonus = 80;  // Bugün yeni bölüm → çok büyük boost
                elseif ($epAge <= 72)  $newEpBonus = 40;  // Son 3 gün
                elseif ($epAge <= 168) $newEpBonus = 15;  // Son 7 gün
                elseif ($epAge <= 720) $newEpBonus = 5;   // Son 30 gün
            }

            // ── Ongoing bonus ─────────────────────────────────────────────────
            $ongoingBonus = ($anime->status === 'ongoing') ? 10 : 0;

            // ── Manuel trending boost ─────────────────────────────────────────
            $manualBoost = $anime->is_trending ? 250 : 0;

            // ── Skor hesapla ─────────────────────────────────────────────────
            $score =
                ($views->v24h ?? 0) * 12 +
                ($views->v7d  ?? 0) * 4  +
                ($views->v30d ?? 0) * 1  +
                $watchMinutes             * 0.8 +
                $newEpBonus +
                $ongoingBonus +
                ((float)($anime->rating ?? 5)) * 4 +
                $manualBoost;

            DB::table('animes')
                ->where('id', $anime->id)
                ->update(['trending_score' => round($score, 2)]);

            $updated++;
        }

        return $updated;
    }

    /**
     * Auto-trending: trending_score'a göre sırala.
     * Fallback: score kolonu yoksa eski yönteme dön.
     */
    public static function getAutoTrending(int $limit = 12): \Illuminate\Support\Collection
    {
        try {
            return Anime::where('is_published', true)
                ->orderByDesc('trending_score')
                ->take($limit)
                ->get();
        } catch (\Throwable) {
            // trending_score kolonu henüz oluşturulmamış → eski yöntem
            return Anime::where('is_published', true)
                ->withSum(['episodes as recent_views' => fn($q) =>
                    $q->where('is_published', true)->where('updated_at', '>=', now()->subDays(30))
                ], 'view_count')
                ->orderByDesc('recent_views')
                ->take($limit)
                ->get();
        }
    }

    private function reorderAll(): void
    {
        $animes = Anime::where('is_trending', true)->orderBy('trending_order')->get();
        foreach ($animes as $i => $a) {
            $a->update(['trending_order' => $i + 1]);
        }
    }
}
