<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Analytics\PageView;
use App\Models\Analytics\WatchEvent;
use App\Models\Analytics\AiQuery;
use App\Models\Analytics\VisitorSession;
use App\Models\Anime;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class AnalyticsController extends Controller
{
    public function index(Request $request)
    {
        $period = $request->input('period', '7d');
        $from   = match ($period) {
            'today' => now()->startOfDay(),
            '30d'   => now()->subDays(30),
            '90d'   => now()->subDays(90),
            default => now()->subDays(7),
        };

        $cacheKey = 'admin_analytics_' . $period;
        $cached   = Cache::remember($cacheKey, 300, function () use ($from, $period) {
            return $this->buildAnalytics($from, $period);
        });
        extract($cached);

        // Gerçek zamanlı veriler (cache'lenmiyor)
        $recentViews = PageView::with('user:id,name')
            ->where('created_at', '>=', $from)
            ->orderByDesc('id')
            ->limit(20)
            ->get();

        $blockedIps = collect();
        $recentBots = collect();
        try {
            $blockedIps = DB::table('blocked_ips')->orderByDesc('blocked_at')->limit(20)->get();
            $recentBots = DB::table('analytics_bot_logs')->orderByDesc('id')->limit(30)->get();
        } catch (\Exception) {}

        return view('admin.analytics.index', compact(
            'period', 'from',
            'totalViews', 'uniqueVisitors', 'watchSeconds', 'aiTotal', 'newUsers',
            'viewsDelta', 'todayViews', 'yesterdayViews',
            'trendLabels', 'trendData', 'watchTrendData',
            'hourlyData',
            'topAnimes',
            'topEpisodes',
            'deviceStats', 'browserStats', 'pageTypeStats',
            'geoStats',
            'activeUsers',
            'aiByType', 'aiTopQuestions', 'aiTopUsers',
            'recentViews',
            'referrerStats', 'directTraffic',
            'botViews', 'humanViews', 'botRatio', 'botTopIps', 'botByName',
            'blockedIps', 'recentBots',
            'sessions', 'avgSessionTime', 'avgPages',
        ));
    }

    private function buildAnalytics($from, string $period): array
    {
        // ── Özet kartlar ──────────────────────────────────────────────────────
        $totalViews     = PageView::where('created_at', '>=', $from)->count();
        $uniqueVisitors = PageView::where('created_at', '>=', $from)->distinct('session_id')->count('session_id');
        $watchSeconds   = WatchEvent::where('created_at', '>=', $from)->sum('seconds_watched');
        $aiTotal        = AiQuery::where('created_at', '>=', $from)->count();
        $newUsers       = User::where('created_at', '>=', $from)->count();

        $yesterday      = now()->subDay();
        $todayViews     = PageView::where('created_at', '>=', now()->startOfDay())->count();
        $yesterdayViews = PageView::whereBetween('created_at', [$yesterday->startOfDay(), $yesterday->endOfDay()])->count();
        $viewsDelta     = $yesterdayViews > 0 ? round(($todayViews - $yesterdayViews) / $yesterdayViews * 100) : 0;

        // ── Görüntüleme trendi (gün bazlı) ────────────────────────────────────
        $viewsByDay = PageView::where('created_at', '>=', $from)
            ->selectRaw('DATE(created_at) as date, COUNT(*) as cnt')
            ->groupBy('date')
            ->orderBy('date')
            ->pluck('cnt', 'date');

        $trendLabels = [];
        $trendData   = [];
        $cur = clone $from;
        while ($cur->lte(now())) {
            $key = $cur->format('Y-m-d');
            $trendLabels[] = $cur->format($period === 'today' ? 'H:i' : 'd M');
            $trendData[]   = $viewsByDay[$key] ?? 0;
            $cur->addDay();
        }

        // ── Saatlik dağılım (bugün) ───────────────────────────────────────────
        $hourlyRaw = PageView::where('created_at', '>=', now()->startOfDay())
            ->selectRaw('HOUR(created_at) as hour, COUNT(*) as cnt')
            ->groupBy('hour')
            ->pluck('cnt', 'hour');
        $hourlyData = array_map(fn($h) => $hourlyRaw[$h] ?? 0, range(0, 23));

        // ── İzleme süresi trendi ─────────────────────────────────────────────
        $watchByDay = WatchEvent::where('created_at', '>=', $from)
            ->selectRaw('DATE(created_at) as date, ROUND(SUM(seconds_watched)/3600, 1) as hours')
            ->groupBy('date')
            ->orderBy('date')
            ->pluck('hours', 'date');
        $watchTrendData = array_map(fn($k) => (float)($watchByDay[$k] ?? 0), array_keys(array_flip($trendLabels)));

        // ── Top 10 anime ─────────────────────────────────────────────────────
        $topAnimeIds = PageView::where('created_at', '>=', $from)
            ->whereNotNull('anime_id')
            ->selectRaw('anime_id, COUNT(*) as cnt')
            ->groupBy('anime_id')
            ->orderByDesc('cnt')
            ->limit(10)
            ->pluck('cnt', 'anime_id');

        $topAnimes = Anime::whereIn('id', $topAnimeIds->keys())
            ->get(['id', 'title', 'cover_image'])
            ->map(fn($a) => [
                'title' => $a->title,
                'views' => $topAnimeIds[$a->id] ?? 0,
                'cover' => $a->cover_url,
                'slug'  => $a->slug,
            ])
            ->sortByDesc('views')
            ->values();

        // ── Top bölümler ─────────────────────────────────────────────────────
        $topEpisodes = WatchEvent::where('analytics_watch_events.created_at', '>=', $from)
            ->selectRaw('anime_id, season_number, episode_number, episode_id,
                          SUM(seconds_watched) as total_sec,
                          COUNT(*) as plays,
                          ROUND(AVG(percent_complete), 0) as avg_pct')
            ->groupBy('anime_id', 'season_number', 'episode_number', 'episode_id')
            ->orderByDesc('total_sec')
            ->limit(10)
            ->get();

        $epAnimes = Anime::whereIn('id', $topEpisodes->pluck('anime_id')->unique())->pluck('title', 'id');
        $topEpisodes = $topEpisodes->map(fn($e) => [
            'anime'   => $epAnimes[$e->anime_id] ?? 'Bilinmiyor',
            'label'   => "S{$e->season_number}E{$e->episode_number}",
            'plays'   => $e->plays,
            'hours'   => round($e->total_sec / 3600, 1),
            'avg_pct' => $e->avg_pct,
        ]);

        // ── Cihaz / tarayıcı / sayfa türü ────────────────────────────────────
        $deviceStats = PageView::where('created_at', '>=', $from)
            ->selectRaw('device, COUNT(*) as cnt')
            ->groupBy('device')
            ->pluck('cnt', 'device');

        $browserStats = PageView::where('created_at', '>=', $from)
            ->selectRaw('browser, COUNT(*) as cnt')
            ->groupBy('browser')
            ->orderByDesc('cnt')
            ->pluck('cnt', 'browser');

        $pageTypeStats = PageView::where('created_at', '>=', $from)
            ->selectRaw('page_type, COUNT(*) as cnt')
            ->groupBy('page_type')
            ->orderByDesc('cnt')
            ->pluck('cnt', 'page_type');

        // ── Coğrafi dağılım ───────────────────────────────────────────────────
        $geoStats = PageView::where('created_at', '>=', $from)
            ->whereNotNull('city')
            ->selectRaw('city, country, COUNT(*) as cnt')
            ->groupBy('city', 'country')
            ->orderByDesc('cnt')
            ->limit(15)
            ->get(['city', 'country', DB::raw('COUNT(*) as cnt')]);

        // ── En aktif kullanıcılar ─────────────────────────────────────────────
        $activeUserIds = PageView::where('created_at', '>=', $from)
            ->whereNotNull('user_id')
            ->selectRaw('user_id, COUNT(*) as views, COUNT(DISTINCT DATE(created_at)) as days')
            ->groupBy('user_id')
            ->orderByDesc('views')
            ->limit(10)
            ->get();

        $activeUserList = User::whereIn('id', $activeUserIds->pluck('user_id'))
            ->get(['id', 'name', 'email', 'created_at'])
            ->keyBy('id');

        $activeUsers = $activeUserIds->map(fn($r) => [
            'user'  => $activeUserList[$r->user_id] ?? null,
            'views' => $r->views,
            'days'  => $r->days,
        ])->filter(fn($r) => $r['user']);

        // ── AI istatistikleri ─────────────────────────────────────────────────
        $aiByType = AiQuery::where('created_at', '>=', $from)
            ->selectRaw('query_type, COUNT(*) as cnt')
            ->groupBy('query_type')
            ->orderByDesc('cnt')
            ->pluck('cnt', 'query_type');

        $aiTopQuestions = AiQuery::where('created_at', '>=', $from)
            ->where('query_type', 'chat')
            ->whereNotNull('query_text')
            ->selectRaw('query_text, COUNT(*) as cnt')
            ->groupBy('query_text')
            ->orderByDesc('cnt')
            ->limit(10)
            ->get();

        $aiByUser = AiQuery::where('created_at', '>=', $from)
            ->whereNotNull('user_id')
            ->selectRaw('user_id, COUNT(*) as cnt')
            ->groupBy('user_id')
            ->orderByDesc('cnt')
            ->limit(5)
            ->get();

        $aiUserList = User::whereIn('id', $aiByUser->pluck('user_id'))->pluck('name', 'id');
        $aiTopUsers = $aiByUser->map(fn($r) => [
            'name' => $aiUserList[$r->user_id] ?? 'Bilinmiyor',
            'cnt'  => $r->cnt,
        ]);

        // ── Referrer ─────────────────────────────────────────────────────────
        $referrerRaw = PageView::where('created_at', '>=', $from)
            ->whereNotNull('referrer')
            ->where('referrer', '!=', '')
            ->selectRaw('referrer, COUNT(*) as cnt')
            ->groupBy('referrer')
            ->orderByDesc('cnt')
            ->limit(30)
            ->pluck('cnt', 'referrer');

        $referrerStats = collect();
        foreach ($referrerRaw as $url => $cnt) {
            try {
                $parsed = parse_url($url);
                $domain = $parsed['host'] ?? $url;
                $domain = preg_replace('/^www\./', '', $domain);
            } catch (\Throwable) {
                $domain = $url;
            }
            if ($referrerStats->has($domain)) {
                $referrerStats[$domain] += $cnt;
            } else {
                $referrerStats[$domain] = $cnt;
            }
        }
        $referrerStats = $referrerStats->sortDesc()->take(15);

        $directTraffic = PageView::where('created_at', '>=', $from)
            ->where(fn($q) => $q->whereNull('referrer')->orWhere('referrer', ''))
            ->count();

        // ── Bot istatistikleri ────────────────────────────────────────────────
        $botViews   = 0;
        $humanViews = 0;
        $botRatio   = 0;
        $botTopIps  = collect();
        $botByName  = collect();

        try {
            $botViews   = PageView::where('created_at', '>=', $from)->where('is_bot', 1)->count();
            $humanViews = PageView::where('created_at', '>=', $from)->where('is_bot', 0)->count();
            $botRatio   = ($botViews + $humanViews) > 0 ? round($botViews / ($botViews + $humanViews) * 100) : 0;

            $botTopIps = DB::table('analytics_bot_logs')
                ->where('created_at', '>=', $from)
                ->selectRaw('ip, COUNT(*) as cnt, MAX(user_agent) as ua, MAX(action) as action')
                ->groupBy('ip')
                ->orderByDesc('cnt')
                ->limit(15)
                ->get();

            $botByName = DB::table('analytics_bot_logs')
                ->where('created_at', '>=', $from)
                ->selectRaw('bot_name, COUNT(*) as cnt, action')
                ->groupBy('bot_name', 'action')
                ->orderByDesc('cnt')
                ->limit(20)
                ->get();
        } catch (\Exception) {}

        // ── Oturum istatistikleri ─────────────────────────────────────────────
        $sessions       = collect();
        $avgSessionTime = 0;
        $avgPages       = 0;

        try {
            $avgSessionTime = (int) DB::table('analytics_sessions')
                ->where('started_at', '>=', $from)
                ->where('is_bot', 0)
                ->avg('total_seconds');

            $avgPages = round((float) DB::table('analytics_sessions')
                ->where('started_at', '>=', $from)
                ->where('is_bot', 0)
                ->avg('pages_visited'), 1);

            $sessions = DB::table('analytics_sessions')
                ->where('started_at', '>=', $from)
                ->orderByDesc('started_at')
                ->limit(30)
                ->get();
        } catch (\Exception) {}

        return compact(
            'totalViews', 'uniqueVisitors', 'watchSeconds', 'aiTotal', 'newUsers',
            'viewsDelta', 'todayViews', 'yesterdayViews',
            'trendLabels', 'trendData', 'watchTrendData',
            'hourlyData',
            'topAnimes', 'topEpisodes',
            'deviceStats', 'browserStats', 'pageTypeStats',
            'geoStats',
            'activeUsers',
            'aiByType', 'aiTopQuestions', 'aiTopUsers',
            'referrerStats', 'directTraffic',
            'botViews', 'humanViews', 'botRatio', 'botTopIps', 'botByName',
            'sessions', 'avgSessionTime', 'avgPages'
        );
    }

    public function blockIp(Request $request)
    {
        $data = $request->validate([
            'ip'         => 'required|ip',
            'reason'     => 'nullable|string|max:255',
            'expires_at' => 'nullable|date|after:now',
        ]);

        DB::table('blocked_ips')->updateOrInsert(
            ['ip' => $data['ip']],
            [
                'reason'       => $data['reason'] ?? 'Manuel engel',
                'auto_blocked' => 0,
                'blocked_at'   => now(),
                'expires_at'   => $data['expires_at'] ?? null,
            ]
        );

        \Illuminate\Support\Facades\Cache::forget('blocked_ip_' . $data['ip']);
        return back()->with('success', $data['ip'] . ' engellendi.');
    }

    public function unblockIp(Request $request)
    {
        $ip = $request->input('ip');
        DB::table('blocked_ips')->where('ip', $ip)->delete();
        \Illuminate\Support\Facades\Cache::forget('blocked_ip_' . $ip);
        return back()->with('success', $ip . ' engeli kaldırıldı.');
    }
}
