<?php

namespace App\Http\Controllers\Frontend;

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

class TrackingController extends Controller
{
    /**
     * POST /track/pageview
     */
    public function pageview(Request $request)
    {
        $data = $request->validate([
            'page_type'   => 'nullable|string|max:30',
            'anime_id'    => 'nullable|integer',
            'episode_id'  => 'nullable|integer',
            'referrer'    => 'nullable|string|max:500',
            'url'         => 'nullable|string|max:500',
            'time_on_page'=> 'nullable|integer|min:0|max:86400',
        ]);

        $ip     = $request->ip();
        $ua     = $request->userAgent() ?? '';
        $isBot  = (bool) $request->attributes->get('is_bot', false);
        $botType= $request->attributes->get('bot_type', null);
        $geo    = self::geoIp($ip);
        $sessId = session()->getId();

        PageView::create([
            'user_id'     => auth()->id(),
            'session_id'  => $sessId,
            'url'         => mb_substr($data['url'] ?? $request->header('Referer', ''), 0, 500),
            'page_type'   => $data['page_type'] ?? 'other',
            'anime_id'    => $data['anime_id'] ?? null,
            'episode_id'  => $data['episode_id'] ?? null,
            'ip'          => $ip,
            'country'     => $geo['country'] ?? null,
            'city'        => $geo['city'] ?? null,
            'device'      => self::detectDevice($ua),
            'browser'     => self::detectBrowser($ua),
            'referrer'    => mb_substr($data['referrer'] ?? '', 0, 500) ?: null,
            'is_bot'      => $isBot ? 1 : 0,
            'user_agent'  => mb_substr($ua, 0, 500),
            'time_on_page'=> $data['time_on_page'] ?? 0,
            'created_at'  => now(),
        ]);

        // Oturum kaydını oluştur / güncelle
        $this->trackSession($sessId, $ip, $ua, $geo, $isBot, $botType, $data);

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

    /**
     * POST /track/watch
     */
    public function watch(Request $request)
    {
        $data = $request->validate([
            'anime_id'       => 'required|integer',
            'episode_id'     => 'nullable|integer',
            'season_number'  => 'required|integer|min:1',
            'episode_number' => 'required|integer|min:1',
            'seconds'        => 'required|integer|min:0',
            'total'          => 'nullable|integer|min:0',
            'percent'        => 'nullable|integer|min:0|max:100',
        ]);

        WatchEvent::create([
            'user_id'         => auth()->id(),
            'session_id'      => session()->getId(),
            'anime_id'        => $data['anime_id'],
            'episode_id'      => $data['episode_id'] ?? null,
            'season_number'   => $data['season_number'],
            'episode_number'  => $data['episode_number'],
            'seconds_watched' => $data['seconds'],
            'total_seconds'   => $data['total'] ?? 0,
            'percent_complete'=> $data['percent'] ?? 0,
            'created_at'      => now(),
        ]);

        // Oturum izleme süresini güncelle
        try {
            DB::table('analytics_sessions')
                ->where('session_id', session()->getId())
                ->increment('total_seconds', (int)$data['seconds']);
        } catch (\Exception) {}

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

    /**
     * POST /track/session-end — sayfa kapanırken JS'ten gönderilir
     */
    public function sessionEnd(Request $request)
    {
        $data = $request->validate([
            'time_on_page' => 'nullable|integer|min:0|max:86400',
        ]);

        try {
            DB::table('analytics_sessions')
                ->where('session_id', session()->getId())
                ->update([
                    'last_seen_at' => now(),
                    'total_seconds'=> DB::raw('total_seconds + ' . (int)($data['time_on_page'] ?? 0)),
                ]);
        } catch (\Exception) {}

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

    // ── Private helpers ──────────────────────────────────────────────────────

    private function trackSession(string $sessId, string $ip, string $ua, array $geo, bool $isBot, ?string $botType, array $data): void
    {
        try {
            $existing = DB::table('analytics_sessions')->where('session_id', $sessId)->first();

            if ($existing) {
                DB::table('analytics_sessions')
                    ->where('session_id', $sessId)
                    ->update([
                        'pages_visited' => DB::raw('pages_visited + 1'),
                        'last_seen_at'  => now(),
                        'user_id'       => auth()->id() ?? $existing->user_id,
                    ]);
            } else {
                DB::table('analytics_sessions')->insert([
                    'session_id'   => $sessId,
                    'user_id'      => auth()->id(),
                    'ip'           => $ip,
                    'country'      => $geo['country'] ?? null,
                    'city'         => $geo['city'] ?? null,
                    'device'       => self::detectDevice($ua),
                    'browser'      => self::detectBrowser($ua),
                    'referrer'     => mb_substr($data['referrer'] ?? '', 0, 500) ?: null,
                    'landing_page' => mb_substr($data['url'] ?? '', 0, 500) ?: null,
                    'pages_visited'=> 1,
                    'total_seconds'=> 0,
                    'is_bot'       => $isBot ? 1 : 0,
                    'bot_type'     => $botType,
                    'user_agent'   => mb_substr($ua, 0, 500),
                    'started_at'   => now(),
                    'last_seen_at' => now(),
                ]);
            }
        } catch (\Exception) {}
    }

    private static function geoIp(string $ip): array
    {
        if ($ip === '127.0.0.1' || str_starts_with($ip, '192.168.') || str_starts_with($ip, '10.')) {
            return ['country' => 'Yerel', 'city' => 'Localhost'];
        }

        return Cache::remember("geo_{$ip}", 86400 * 7, function () use ($ip) {
            try {
                $r = Http::timeout(2)->get("http://ip-api.com/json/{$ip}?fields=country,city,status");
                if ($r->ok() && $r->json('status') === 'success') {
                    return ['country' => $r->json('country'), 'city' => $r->json('city')];
                }
            } catch (\Exception) {}
            return ['country' => null, 'city' => null];
        });
    }

    private static function detectDevice(string $ua): string
    {
        $ua = strtolower($ua);
        if (str_contains($ua, 'tablet') || str_contains($ua, 'ipad')) return 'tablet';
        if (str_contains($ua, 'mobile') || str_contains($ua, 'android') || str_contains($ua, 'iphone')) return 'mobile';
        return 'desktop';
    }

    private static function detectBrowser(string $ua): string
    {
        if (str_contains($ua, 'Edg/'))     return 'Edge';
        if (str_contains($ua, 'OPR/') || str_contains($ua, 'Opera')) return 'Opera';
        if (str_contains($ua, 'Chrome'))   return 'Chrome';
        if (str_contains($ua, 'Firefox'))  return 'Firefox';
        if (str_contains($ua, 'Safari'))   return 'Safari';
        if (str_contains($ua, 'MSIE') || str_contains($ua, 'Trident')) return 'IE';
        return 'Other';
    }
}
