import sqlite3
import pandas as pd
import numpy as np
import os

DB_L2_PATH = r'd:\Documents\trae_projects\yrtv\database\L2\L2_Main.sqlite'

def get_db_connection():
    conn = sqlite3.connect(DB_L2_PATH)
    conn.row_factory = sqlite3.Row
    return conn

def load_data_and_calculate(conn, min_matches=5):
    print("Loading Basic Stats...")
    
    # 1. Basic Stats
    query_basic = """
    SELECT 
        steam_id_64,
        COUNT(*) as matches_played,
        AVG(rating) as avg_rating,
        AVG(kd_ratio) as avg_kd,
        AVG(adr) as avg_adr,
        AVG(kast) as avg_kast,
        SUM(first_kill) as total_fk,
        SUM(first_death) as total_fd,
        SUM(clutch_1v1) + SUM(clutch_1v2) + SUM(clutch_1v3) + SUM(clutch_1v4) + SUM(clutch_1v5) as total_clutches,
        SUM(throw_harm) as total_util_dmg,
        SUM(flash_time) as total_flash_time,
        SUM(flash_enemy) as total_flash_enemy
    FROM fact_match_players
    GROUP BY steam_id_64
    HAVING COUNT(*) >= ?
    """
    df_basic = pd.read_sql_query(query_basic, conn, params=(min_matches,))
    
    valid_ids = tuple(df_basic['steam_id_64'].tolist())
    if not valid_ids:
        print("No players found.")
        return None
    placeholders = ','.join(['?'] * len(valid_ids))
    
    # 2. Side Stats (T/CT) via Economy Table (which has side info)
    print("Loading Side Stats via Round Map...")
    # Map each round+player to a side
    query_side_map = f"""
    SELECT match_id, round_num, steam_id_64, side
    FROM fact_round_player_economy
    WHERE steam_id_64 IN ({placeholders})
    """
    try:
        df_sides = pd.read_sql_query(query_side_map, conn, params=valid_ids)
        
        # Get all Kills
        query_kills = f"""
        SELECT match_id, round_num, attacker_steam_id as steam_id_64, COUNT(*) as kills
        FROM fact_round_events
        WHERE event_type = 'kill'
        AND attacker_steam_id IN ({placeholders})
        GROUP BY match_id, round_num, attacker_steam_id
        """
        df_kills = pd.read_sql_query(query_kills, conn, params=valid_ids)
        
        # Merge to get Kills per Side
        df_merged = df_kills.merge(df_sides, on=['match_id', 'round_num', 'steam_id_64'], how='inner')
        
        # Aggregate
        side_stats = df_merged.groupby(['steam_id_64', 'side'])['kills'].sum().unstack(fill_value=0)
        side_stats.columns = [f'kills_{c.lower()}' for c in side_stats.columns]
        
        # Also need deaths to calc KD (approx)
        # Assuming deaths are in events as victim
        query_deaths = f"""
        SELECT match_id, round_num, victim_steam_id as steam_id_64, COUNT(*) as deaths
        FROM fact_round_events
        WHERE event_type = 'kill'
        AND victim_steam_id IN ({placeholders})
        GROUP BY match_id, round_num, victim_steam_id
        """
        df_deaths = pd.read_sql_query(query_deaths, conn, params=valid_ids)
        df_merged_d = df_deaths.merge(df_sides, on=['match_id', 'round_num', 'steam_id_64'], how='inner')
        side_stats_d = df_merged_d.groupby(['steam_id_64', 'side'])['deaths'].sum().unstack(fill_value=0)
        side_stats_d.columns = [f'deaths_{c.lower()}' for c in side_stats_d.columns]
        
        # Combine
        df_side_final = side_stats.join(side_stats_d).fillna(0)
        df_side_final['ct_kd'] = df_side_final.get('kills_ct', 0) / df_side_final.get('deaths_ct', 1).replace(0, 1)
        df_side_final['t_kd'] = df_side_final.get('kills_t', 0) / df_side_final.get('deaths_t', 1).replace(0, 1)
        
    except Exception as e:
        print(f"Side stats failed: {e}")
        df_side_final = pd.DataFrame({'steam_id_64': list(valid_ids)})

    # 3. PTL (Pistol) via Rounds 1 and 13
    print("Loading Pistol Stats via Rounds...")
    query_pistol_kills = f"""
    SELECT 
        ev.attacker_steam_id as steam_id_64,
        COUNT(*) as pistol_kills
    FROM fact_round_events ev
    WHERE ev.attacker_steam_id IN ({placeholders})
    AND ev.event_type = 'kill'
    AND ev.round_num IN (1, 13)
    GROUP BY ev.attacker_steam_id
    """
    df_ptl = pd.read_sql_query(query_pistol_kills, conn, params=valid_ids)
    
    # 4. HPS
    print("Loading HPS Stats...")
    query_close = f"""
    SELECT mp.steam_id_64, AVG(mp.rating) as close_match_rating
    FROM fact_match_players mp
    JOIN fact_matches m ON mp.match_id = m.match_id
    WHERE mp.steam_id_64 IN ({placeholders})
    AND ABS(m.score_team1 - m.score_team2) <= 3
    GROUP BY mp.steam_id_64
    """
    df_hps = pd.read_sql_query(query_close, conn, params=valid_ids)
    
    # 5. STA
    query_sta = f"""
    SELECT mp.steam_id_64, mp.rating, mp.is_win
    FROM fact_match_players mp
    WHERE mp.steam_id_64 IN ({placeholders})
    """
    df_matches = pd.read_sql_query(query_sta, conn, params=valid_ids)
    sta_data = []
    for pid, group in df_matches.groupby('steam_id_64'):
        rating_std = group['rating'].std()
        win_rating = group[group['is_win']==1]['rating'].mean()
        loss_rating = group[group['is_win']==0]['rating'].mean()
        sta_data.append({'steam_id_64': pid, 'rating_std': rating_std, 'win_rating': win_rating, 'loss_rating': loss_rating})
    df_sta = pd.DataFrame(sta_data)

    # --- Merge All ---
    df = df_basic.merge(df_side_final, on='steam_id_64', how='left')
    df = df.merge(df_hps, on='steam_id_64', how='left')
    df = df.merge(df_ptl, on='steam_id_64', how='left').fillna(0)
    df = df.merge(df_sta, on='steam_id_64', how='left')
    
    return df

def normalize_series(series):
    min_v = series.min()
    max_v = series.max()
    if pd.isna(min_v) or pd.isna(max_v) or min_v == max_v:
        return pd.Series([50]*len(series), index=series.index)
    return (series - min_v) / (max_v - min_v) * 100

def calculate_scores(df):
    df = df.copy()
    
    # BAT
    df['n_rating'] = normalize_series(df['avg_rating'])
    df['n_kd'] = normalize_series(df['avg_kd'])
    df['n_adr'] = normalize_series(df['avg_adr'])
    df['n_kast'] = normalize_series(df['avg_kast'])
    df['score_BAT'] = 0.4*df['n_rating'] + 0.3*df['n_kd'] + 0.2*df['n_adr'] + 0.1*df['n_kast']
    
    # STA
    df['n_std'] = normalize_series(df['rating_std'].fillna(0))
    df['n_win_r'] = normalize_series(df['win_rating'].fillna(0))
    df['n_loss_r'] = normalize_series(df['loss_rating'].fillna(0))
    df['score_STA'] = 0.5*(100 - df['n_std']) + 0.25*df['n_win_r'] + 0.25*df['n_loss_r']
    
    # UTIL
    df['n_util_dmg'] = normalize_series(df['total_util_dmg'] / df['matches_played'])
    df['n_flash'] = normalize_series(df['total_flash_time'] / df['matches_played'])
    df['score_UTIL'] = 0.6*df['n_util_dmg'] + 0.4*df['n_flash']
    
    # T/CT (Calculated from Event Logs)
    df['n_ct_kd'] = normalize_series(df['ct_kd'].fillna(0))
    df['n_t_kd'] = normalize_series(df['t_kd'].fillna(0))
    df['score_TCT'] = 0.5*df['n_ct_kd'] + 0.5*df['n_t_kd']
    
    # HPS
    df['n_clutch'] = normalize_series(df['total_clutches'] / df['matches_played'])
    df['n_close_r'] = normalize_series(df['close_match_rating'].fillna(0))
    df['score_HPS'] = 0.5*df['n_clutch'] + 0.5*df['n_close_r']
    
    # PTL
    df['n_pistol'] = normalize_series(df['pistol_kills'] / df['matches_played'])
    df['score_PTL'] = df['n_pistol']
    
    return df

def main():
    conn = get_db_connection()
    try:
        df = load_data_and_calculate(conn)
        if df is None: return
        
        # Debug: Print raw stats for checking T/CT issue
        print("\n--- Raw T/CT Stats Sample ---")
        if 'ct_kd' in df.columns:
            print(df[['steam_id_64', 'ct_kd', 't_kd']].head())
        else:
            print("CT/KD columns missing")
            
        results = calculate_scores(df)
        
        print("\n--- Final Dimension Scores (Top 5 by BAT) ---")
        cols = ['steam_id_64', 'score_BAT', 'score_STA', 'score_UTIL', 'score_TCT', 'score_HPS', 'score_PTL']
        print(results[cols].sort_values('score_BAT', ascending=False).head(5))
        
    except Exception as e:
        print(f"Error: {e}")
        import traceback
        traceback.print_exc()
    finally:
        conn.close()

if __name__ == "__main__":
    main()
