"""
VQWEN Live Prediction Tracker
=============================
Predicts today's upcoming matches (from live_matches) and tracks results.
"""

import os
import sys
import json
import time
import pickle
import psycopg2
import pandas as pd
import numpy as np
from psycopg2.extras import RealDictCursor

AI_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(AI_DIR)
PROJECT_ROOT = os.path.dirname(ROOT_DIR)

def get_clean_dsn() -> str:
    return "postgresql://suggestbet:SuGGesT2026SecuRe@localhost:15432/boilerplate_db"

def run_live_predictions():
    print("🔴 VQWEN LIVE PREDICTION TRACKER")
    print("="*60)

    # Load Models
    mdir = os.path.join(ROOT_DIR, 'models', 'vqwen')
    try:
        with open(os.path.join(mdir, 'vqwen_ms.pkl'), 'rb') as f: model_ms = pickle.load(f)
        with open(os.path.join(mdir, 'vqwen_ou25.pkl'), 'rb') as f: model_ou = pickle.load(f)
        with open(os.path.join(mdir, 'vqwen_btts.pkl'), 'rb') as f: model_btts = pickle.load(f)
        print("✅ VQWEN v3 modelleri yüklendi.")
    except Exception as e:
        print(f"❌ Model hatası: {e}")
        return

    dsn = get_clean_dsn()
    conn = psycopg2.connect(dsn)
    cur = conn.cursor(cursor_factory=RealDictCursor)

    # 1. Bugünün Maçlarını Çek (NS veya oynanıyor ama henüz bitmemiş olanlar)
    # mst_utc bugün olan maçlar
    start_of_day = int(time.mktime(time.strptime(time.strftime("%Y-%m-%d"), "%Y-%m-%d")) * 1000)
    end_of_day = start_of_day + (24 * 60 * 60 * 1000)

    print(f"📅 Bugünün maçları taranıyor...")
    
    # live_matches veya matches tablosundan bugünkü maçları alıyoruz
    # Önce odds olanları alalım
    cur.execute("""
        SELECT m.id, m.home_team_id, m.away_team_id, m.score_home, m.score_away, 
               m.mst_utc, m.status,
               t1.name as home_team, t2.name as away_team,
               l.name as league_name,
               maf.home_elo, maf.away_elo
        FROM live_matches m
        LEFT JOIN teams t1 ON m.home_team_id = t1.id
        LEFT JOIN teams t2 ON m.away_team_id = t2.id
        LEFT JOIN leagues l ON m.league_id = l.id
        LEFT JOIN football_ai_features maf ON maf.match_id = m.id
        WHERE m.mst_utc >= %s AND m.mst_utc <= %s
        ORDER BY m.mst_utc ASC
    """, (start_of_day, end_of_day))
    
    rows = cur.fetchall()
    print(f"📊 Bugün için {len(rows)} maç bulundu.")

    if not rows:
        print("⚠️ Bugün için oranı olan maç bulunamadı.")
        cur.close()
        conn.close()
        return

    results = []
    total_profit = 0.0
    total_bet = 0
    total_won = 0

    for i, row in enumerate(rows):
        match_id = str(row['id'])
        home = row['home_team'] or "Home"
        away = row['away_team'] or "Away"
        league = row['league_name'] or "Unknown"
        
        # Maç bitmiş mi kontrol et
        is_finished = row['status'] in ['FT', 'AET', 'PEN', 'post', 'postGame'] or (
            row['score_home'] is not None and row['score_away'] is not None and
            row['status'] not in ['NS', 'pre', 'preGame', 'live', 'liveGame']
        )

        # Oranları al (odd_categories)
        cur.execute("""
            SELECT oc.name as category, os.name as selection, os.odd_value
            FROM odd_categories oc
            JOIN odd_selections os ON os.odd_category_db_id = oc.db_id
            WHERE oc.match_id = %s AND oc.name ILIKE ANY (ARRAY['%%Maç Sonucu%%', '%%2,5 Alt/Üst%%', '%%Karşılıklı Gol%%'])
        """, (match_id,))
        odds_rows = cur.fetchall()
        
        odds_dict = {}
        for o in odds_rows:
            cat = o['category'].lower()
            sel = o['selection'].lower()
            val = float(o['odd_value'])
            if 'maç sonucu' in cat or 'mac sonucu' in cat:
                if sel == '1': odds_dict['ms_h'] = val
                elif sel == 'x': odds_dict['ms_d'] = val
                elif sel == '2': odds_dict['ms_a'] = val
            elif '2,5 alt' in cat or '2.5 alt' in cat:
                if 'alt' in sel: odds_dict['ou25_u'] = val
                elif 'üst' in sel or 'ust' in sel: odds_dict['ou25_o'] = val
            elif 'karşılıklı gol' in cat:
                if 'var' in sel: odds_dict['btts_y'] = val
                elif 'yok' in sel: odds_dict['btts_n'] = val

        # Eğer oranlar yoksa atla
        if not all(k in odds_dict for k in ['ms_h', 'ms_d', 'ms_a', 'ou25_o', 'btts_y']):
            # print(f"⚠️ {home} vs {away} - Oranlar eksik.")
            continue

        # Özellikleri Hesapla
        # Form, Rest, Contextual Goals veritabanından çekilmeli (canlı maç için)
        cur.execute("""
            SELECT 
                COALESCE((SELECT AVG(m2.score_home) FROM matches m2 WHERE m2.home_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s), 1.2) as h_home_goals,
                COALESCE((SELECT AVG(m2.score_away) FROM matches m2 WHERE m2.away_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s), 1.2) as a_away_goals,
                COALESCE(EXTRACT(EPOCH FROM (to_timestamp(%s/1000) - (SELECT MAX(to_timestamp(m2.mst_utc/1000)) FROM matches m2 WHERE m2.home_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s)) / 86400), 7) as h_rest,
                COALESCE(EXTRACT(EPOCH FROM (to_timestamp(%s/1000) - (SELECT MAX(to_timestamp(m2.mst_utc/1000)) FROM matches m2 WHERE m2.away_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s)) / 86400), 7) as a_rest,
                COALESCE((SELECT COUNT(*) FROM match_player_participation mp WHERE mp.match_id = %s AND mp.team_id = %s AND mp.is_starting = true), 11) as h_xi,
                COALESCE((SELECT COUNT(*) FROM match_player_participation mp WHERE mp.match_id = %s AND mp.team_id = %s AND mp.is_starting = true), 11) as a_xi,
                COALESCE((SELECT COUNT(*) FILTER (WHERE m2.score_home > m2.score_away)::float / NULLIF(COUNT(*), 0) FROM matches m2 WHERE m2.home_team_id = %s AND m2.away_team_id = m2.away_team_id AND m2.status = 'FT' AND m2.mst_utc < %s), 0.5) as h2h_h_wr,
                COALESCE((SELECT SUM(pts) FROM (SELECT CASE WHEN m2.score_home > m2.score_away THEN 3 WHEN m2.score_home = m2.score_away THEN 1 ELSE 0 END as pts FROM matches m2 WHERE m2.home_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s ORDER BY m2.mst_utc DESC LIMIT 5) sub), 0) as h_form_pts,
                COALESCE((SELECT SUM(pts) FROM (SELECT CASE WHEN m2.score_away > m2.score_home THEN 3 WHEN m2.score_away = m2.score_home THEN 1 ELSE 0 END as pts FROM matches m2 WHERE m2.away_team_id = %s AND m2.status = 'FT' AND m2.mst_utc < %s ORDER BY m2.mst_utc DESC LIMIT 5) sub), 0) as a_form_pts
        """, (
            row['home_team_id'], row['mst_utc'],
            row['away_team_id'], row['mst_utc'],
            row['mst_utc'], row['home_team_id'], row['mst_utc'],
            row['mst_utc'], row['away_team_id'], row['mst_utc'],
            match_id, row['home_team_id'],
            match_id, row['away_team_id'],
            row['home_team_id'], row['away_team_id'], row['mst_utc'],
            row['home_team_id'], row['mst_utc'],
            row['away_team_id'], row['mst_utc']
        ))
        stats = cur.fetchone()

        h_elo = float(row['home_elo'] or 1500)
        a_elo = float(row['away_elo'] or 1500)
        h_home_goals = float(stats['h_home_goals'] or 1.2)
        a_away_goals = float(stats['a_away_goals'] or 1.2)
        h_rest = float(stats['h_rest'] or 7)
        a_rest = float(stats['a_rest'] or 7)
        h_xi = float(stats['h_xi'] or 11)
        a_xi = float(stats['a_xi'] or 11)
        h2h_h_wr = float(stats['h2h_h_wr'] or 0.5)
        h_pts = float(stats['h_form_pts'] or 0)
        a_pts = float(stats['a_form_pts'] or 0)

        def fatigue(rest):
            if rest < 3: return 0.85
            if rest < 5: return 0.95
            return 1.0

        h_fat = fatigue(h_rest)
        a_fat = fatigue(a_rest)
        h_xg = h_home_goals * h_fat
        a_xg = a_away_goals * a_fat
        margin = (1/odds_dict['ms_h']) + (1/odds_dict['ms_d']) + (1/odds_dict['ms_a'])

        features = pd.DataFrame([{
            'elo_diff': h_elo - a_elo,
            'h_xg': h_xg, 'a_xg': a_xg,
            'total_xg': h_xg + a_xg,
            'pow_diff': (h_elo/100)*h_fat - (a_elo/100)*a_fat,
            'rest_diff': h_rest - a_rest,
            'h_fatigue': h_fat, 'a_fatigue': a_fat,
            'imp_h': (1/odds_dict['ms_h'])/margin, 
            'imp_d': (1/odds_dict['ms_d'])/margin, 
            'imp_a': (1/odds_dict['ms_a'])/margin,
            'h_xi': h_xi, 'a_xi': a_xi,
            'h2h_h_wr': h2h_h_wr, 
            'form_diff': h_pts - a_pts
        }])

        # --- TAHMİNLER ---
        ms_probs = model_ms.predict(features)[0]
        p_over = float(model_ou.predict(features)[0])
        p_btts = float(model_btts.predict(features)[0])

        # --- EN İYİ VALUE PICK ---
        picks = []
        for pick, prob, odd in zip(['1', 'X', '2'], ms_probs, [odds_dict['ms_h'], odds_dict['ms_d'], odds_dict['ms_a']]):
            edge = prob - (1/odd)
            if edge > 0.05 and prob > 0.45:
                picks.append({"market": "MS", "pick": pick, "prob": prob, "odds": odd})
        
        if p_over > 0.55: picks.append({"market": "OU2.5", "pick": "Over", "prob": p_over, "odds": odds_dict.get('ou25_o', 1.85)})
        if p_btts > 0.55: picks.append({"market": "BTTS", "pick": "Var", "prob": p_btts, "odds": odds_dict.get('btts_y', 1.85)})

        picks.sort(key=lambda x: (x['prob'] + max(0, x['prob'] - 1/x['odds'])*100), reverse=True)
        best_pick = picks[0] if picks else None

        # --- SONUÇ KONTROLÜ ---
        res_str = "⏳ Oynanıyor/Bekleniyor"
        won = None
        h_score = row['score_home']
        a_score = row['score_away']

        if is_finished and h_score is not None and a_score is not None:
            res_str = f"🏁 SONUÇ: {h_score}-{a_score}"
            if best_pick:
                p = best_pick['pick']
                if p == '1': won = h_score > a_score
                elif p == 'X': won = h_score == a_score
                elif p == '2': won = a_score > h_score
                elif p == 'Over': won = (h_score + a_score) > 2.5
                elif p == 'Var': won = h_score > 0 and a_score > 0
                
                res_str += " | " + ("✅ KAZANDI" if won else "❌ KAYBETTİ")
                if won: total_profit += (best_pick['odds'] - 1.0)
                else: total_profit -= 1.0
                total_bet += 1
                if won: total_won += 1

        # Çıktı
        match_time = time.strftime("%H:%M", time.gmtime(row['mst_utc']/1000))
        pick_info = f"{best_pick['market']} - {best_pick['pick']} (%{best_pick['prob']*100:.0f} @ {best_pick['odds']:.2f})" if best_pick else "💤 Önerilen Bahis Yok"
        
        print(f"\n⚽ [{match_time}] {home} vs {away} ({league})")
        print(f"   🧠 Tahmin: {pick_info}")
        print(f"   {res_str}")

    print("\n" + "="*60)
    print("📊 GÜNLÜK ÖZET")
    print("="*60)
    if total_bet > 0:
        print(f"🎲 Oynanan Bahis: {total_bet}")
        print(f"✅ Kazanan: {total_won}")
        print(f"💰 Toplam Kâr: {total_profit:.2f} Units")
        print(f"📈 ROI: {(total_profit/total_bet)*100:.1f}%")
    else:
        print("📝 Bugün için Value Bahis bulunamadı veya maçlar bitmedi.")

    cur.close()
    conn.close()

if __name__ == "__main__":
    run_live_predictions()
