"""
VQWEN Full Backtest
===================
Tests all 3 VQWEN models (MS, OU25, BTTS) on 1000 historical matches.
"""

import os
import sys
import json
import pickle
import pandas as pd
import numpy as np
import psycopg2
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_vqwen_backtest():
    print("🧠 VQWEN FULL BACKTEST")
    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 MS, OU25, BTTS modelleri yüklendi.")
    except Exception as e:
        print(f"❌ Model hatası: {e}")
        return

    with open(os.path.join(PROJECT_ROOT, "top_leagues.json"), 'r') as f:
        league_ids = tuple(str(lid) for lid in json.load(f))

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

    cur.execute("""
        SELECT m.id, m.home_team_id, m.away_team_id, m.score_home, m.score_away,
               t1.name as home_team, t2.name as away_team,
               (SELECT os.odd_value FROM odd_categories oc JOIN odd_selections os ON os.odd_category_db_id = oc.db_id WHERE oc.match_id = m.id AND oc.name ILIKE 'Maç Sonucu' AND os.name = '1' LIMIT 1) as oh,
               (SELECT os.odd_value FROM odd_categories oc JOIN odd_selections os ON os.odd_category_db_id = oc.db_id WHERE oc.match_id = m.id AND oc.name ILIKE 'Maç Sonucu' AND os.name = 'X' LIMIT 1) as od,
               (SELECT os.odd_value FROM odd_categories oc JOIN odd_selections os ON os.odd_category_db_id = oc.db_id WHERE oc.match_id = m.id AND oc.name ILIKE 'Maç Sonucu' AND os.name = '2' LIMIT 1) as oa,
               COALESCE((SELECT AVG(CASE WHEN m2.home_team_id = m.home_team_id AND m2.score_home > m2.score_away THEN 3 WHEN m2.home_team_id = m.home_team_id AND m2.score_home = m2.score_away THEN 1 ELSE 0 END) FROM matches m2 WHERE m2.home_team_id = m.home_team_id AND m2.status = 'FT' AND m2.mst_utc < m.mst_utc LIMIT 5), 0) as h_form,
               COALESCE((SELECT AVG(CASE WHEN m2.away_team_id = m.away_team_id AND m2.score_away > m2.score_home THEN 3 WHEN m2.away_team_id = m.away_team_id AND m2.score_away = m2.score_home THEN 1 ELSE 0 END) FROM matches m2 WHERE m2.away_team_id = m.away_team_id AND m2.status = 'FT' AND m2.mst_utc < m.mst_utc LIMIT 5), 0) as a_form,
               COALESCE((SELECT AVG(m2.score_home) FROM matches m2 WHERE m2.home_team_id = m.home_team_id AND m2.status = 'FT' LIMIT 10), 1.2) as h_sc,
               COALESCE((SELECT AVG(m2.score_away) FROM matches m2 WHERE m2.away_team_id = m.home_team_id AND m2.status = 'FT' LIMIT 10), 1.2) as h_co,
               COALESCE((SELECT AVG(m2.score_away) FROM matches m2 WHERE m2.away_team_id = m.away_team_id AND m2.status = 'FT' LIMIT 10), 1.2) as a_sc,
               COALESCE((SELECT AVG(m2.score_home) FROM matches m2 WHERE m2.home_team_id = m.away_team_id AND m2.status = 'FT' LIMIT 10), 1.2) as a_co
        FROM matches m
        LEFT JOIN teams t1 ON m.home_team_id = t1.id
        LEFT JOIN teams t2 ON m.away_team_id = t2.id
        WHERE m.league_id IN %s AND m.status = 'FT' AND m.score_home IS NOT NULL
        ORDER BY m.mst_utc DESC
        LIMIT 1000
    """, (league_ids,))
    
    rows = cur.fetchall()
    print(f"📊 {len(rows)} maç analiz ediliyor...")

    results = {'ms': {'bet': 0, 'won': 0, 'profit': 0}, 'ou25': {'bet': 0, 'won': 0, 'profit': 0}, 'btts': {'bet': 0, 'won': 0, 'profit': 0}}

    for row in rows:
        oh, od, oa = float(row['oh'] or 0), float(row['od'] or 0), float(row['oa'] or 0)
        if oh <= 1.0 or od <= 1.0 or oa <= 1.0: continue

        h_xg = (float(row['h_sc'] or 1.2) + float(row['a_co'] or 1.2)) / 2
        a_xg = (float(row['a_sc'] or 1.2) + float(row['h_co'] or 1.2)) / 2
        h_p = (float(row['h_form'] or 0)*10) + (float(row['h_sc'] or 1.2)*5) - (float(row['h_co'] or 1.2)*5)
        a_p = (float(row['a_form'] or 0)*10) + (float(row['a_sc'] or 1.2)*5) - (float(row['a_co'] or 1.2)*5)
        
        margin = (1/oh) + (1/od) + (1/oa)
        
        # MS Prediction
        f_ms = pd.DataFrame([{'h_form': float(row['h_form']), 'a_form': float(row['a_form']), 'h_xg': h_xg, 'a_xg': a_xg, 
                              'pow_diff': h_p - a_p, 'imp_h': (1/oh)/margin, 'imp_d': (1/od)/margin, 'imp_a': (1/oa)/margin,
                              'h_sot': 4.0, 'a_sot': 3.0}])
        ms_probs = model_ms.predict(f_ms)[0]
        
        # MS Value Bet
        for i, (pick, prob, odd) in enumerate(zip(['1', 'X', '2'], ms_probs, [oh, od, oa])):
            if odd <= 1.0: continue
            edge = prob - (1/odd)
            if edge > 0.05 and prob > 0.50: # Value ve Güven
                results['ms']['bet'] += 1
                h, a = row['score_home'], row['score_away']
                w = (pick=='1' and h>a) or (pick=='X' and h==a) or (pick=='2' and a>h)
                if w: results['ms']['won'] += 1; results['ms']['profit'] += (odd - 1.0)
                else: results['ms']['profit'] -= 1.0
                break

        # OU2.5 Prediction
        f_ou = pd.DataFrame([{'h_xg': h_xg, 'a_xg': a_xg, 'total_xg': h_xg+a_xg, 'h_sot': 4.0, 'a_sot': 3.0}])
        p_over = model_ou.predict(f_ou)[0]
        
        # OU2.5 Value Bet
        if p_over > 0.55 and oh > 1.0: # Sadece örnek olarak over > %55 ise
            results['ou25']['bet'] += 1
            if (row['score_home'] + row['score_away']) > 2.5: results['ou25']['won'] += 1; results['ou25']['profit'] += 0.85 # Ortalama oran
            else: results['ou25']['profit'] -= 1.0

        # BTTS Prediction
        f_btts = pd.DataFrame([{'h_xg': h_xg, 'a_xg': a_xg, 'h_sc': float(row['h_sc']), 'a_sc': float(row['a_sc'])}])
        p_btts = model_btts.predict(f_btts)[0]
        
        # BTTS Value Bet
        if p_btts > 0.55:
            results['btts']['bet'] += 1
            if row['score_home'] > 0 and row['score_away'] > 0: results['btts']['won'] += 1; results['btts']['profit'] += 0.85
            else: results['btts']['profit'] -= 1.0

    print("\n" + "="*60)
    print("📊 VQWEN PAZAR BAZLI SONUÇLAR")
    print("="*60)
    for mkt in ['ms', 'ou25', 'btts']:
        r = results[mkt]
        wr = (r['won'] / r['bet'] * 100) if r['bet'] > 0 else 0
        print(f"{mkt.upper():<10} Oynanan: {r['bet']:<5} Kazanılan: {r['won']:<5} WR: {wr:.1f}%  Kâr: {r['profit']:+.2f} Units")
    
    total_profit = sum(r['profit'] for r in results.values())
    print(f"\n💰 TOPLAM KÂR: {total_profit:+.2f} Units")
    if total_profit > 0: print("🟢 PARA KAZANDIK!")
    else: print("🔴 ZARARDA")

    cur.close()
    conn.close()

if __name__ == "__main__":
    run_vqwen_backtest()
