#!/usr/bin/env python3
"""
NBA Injury Impact Metrics
Calculates team performance vs injured opponents and line movement impact.
"""
import psycopg2
from datetime import datetime, timezone, timedelta


def load_db_url():
    with open('/var/www/html/eventheodds/.env', 'r') as f:
        for line in f:
            if line.startswith('SPORTS_DATABASE_URL='):
                return line.split('=', 1)[1].strip().split('?')[0]
    return ''


TEAM_MAP = {
    '76ERS': 'PHI',
    'BUCKS': 'MIL',
    'BULLS': 'CHI',
    'CAVALIERS': 'CLE',
    'CELTICS': 'BOS',
    'CLIPPERS': 'LAC',
    'GRIZZLIES': 'MEM',
    'HAWKS': 'ATL',
    'HEAT': 'MIA',
    'HORNETS': 'CHA',
    'JAZZ': 'UTA',
    'KINGS': 'SAC',
    'KNICKS': 'NYK',
    'LAKERS': 'LAL',
    'MAGIC': 'ORL',
    'MAVERICKS': 'DAL',
    'NETS': 'BKN',
    'NUGGETS': 'DEN',
    'PACERS': 'IND',
    'PELICANS': 'NOP',
    'PISTONS': 'DET',
    'RAPTORS': 'TOR',
    'ROCKETS': 'HOU',
    'SPURS': 'SAS',
    'SUNS': 'PHX',
    'THUNDER': 'OKC',
    'TIMBERWOLVES': 'MIN',
    'TRAIL BLAZERS': 'POR',
    'BLAZERS': 'POR',
    'WARRIORS': 'GSW',
    'WIZARDS': 'WAS',
}


def normalize_team(team: str) -> str:
    if not team:
        return ''
    key = team.strip().upper()
    return TEAM_MAP.get(key, key)


def ingest_injury_impact(season=2024):
    db_url = load_db_url()
    if not db_url:
        raise RuntimeError('SPORTS_DATABASE_URL not set')

    conn = psycopg2.connect(db_url)
    cur = conn.cursor()

    game_key = f'{season}_NBA_INJURY'
    game_date = datetime(season, 10, 1, tzinfo=timezone.utc)

    sql_upsert = '''
        INSERT INTO "TeamGameMetric"
        (league, season, "gameKey", "gameDate", team, "statKey", value)
        VALUES (%s, %s, %s, %s, %s, %s, %s)
        ON CONFLICT (league, season, "gameKey", team, "statKey")
        DO UPDATE SET value = EXCLUDED.value
    '''

    cur.execute(
        """
        SELECT id, "gameDate", "homeTeam", "awayTeam", "homeScore", "awayScore", "spreadHome"
        FROM "SportsGame"
        WHERE league = 'nba' AND season = %s AND "homeScore" IS NOT NULL AND "awayScore" IS NOT NULL
        """,
        (season,)
    )
    games = cur.fetchall()

    # Aggregate per team
    agg = {}

    for game_id, game_dt, home_team, away_team, home_score, away_score, spread_home in games:
        # Injury count for opponent (active injuries near game date)
        window_start = game_dt - timedelta(days=45)
        window_end = game_dt + timedelta(days=1)

        cur.execute(
            """
            SELECT p.team, COUNT(*)
            FROM "PlayerInjury" i
            JOIN "Player" p
              ON p.league = i.league
             AND p."externalPlayerId" = i."playerExternalId"
            WHERE i.league = 'nba'
              AND i.status IN ('Out','Questionable','Doubtful','Day-To-Day','Probable')
              AND COALESCE(i."sourceUpdatedAt", i."createdAt") BETWEEN %s AND %s
              AND p.team IS NOT NULL
            GROUP BY p.team
            """,
            (window_start, window_end)
        )
        injury_counts = {row[0]: row[1] for row in cur.fetchall()}

        home_norm = normalize_team(home_team)
        away_norm = normalize_team(away_team)

        for team, opp, team_score, opp_score, spread in [
            (home_norm, away_norm, home_score, away_score, spread_home),
            (away_norm, home_norm, away_score, home_score, -spread_home if spread_home is not None else None)
        ]:
            opp_inj = injury_counts.get(opp, 0)
            if opp_inj < 3:
                continue

            margin = team_score - opp_score
            covered = None
            if spread is not None:
                covered = 1 if margin > -spread else 0.5 if margin == -spread else 0

            agg.setdefault(team, {
                'games': 0,
                'covers': 0.0,
                'cover_games': 0,
                'margin': 0.0,
                'line_move': 0.0,
                'line_move_count': 0
            })
            agg[team]['games'] += 1
            agg[team]['margin'] += (margin + (spread if spread is not None else 0))
            if covered is not None:
                agg[team]['covers'] += covered
                agg[team]['cover_games'] += 1

            # Approx line movement from GameOdds (spread)
            cur.execute(
                """
                SELECT ABS("lineValue" - "openingLineValue")
                FROM "GameOdds"
                WHERE league = 'nba'
                  AND market = 'spreads'
                  AND "openingLineValue" IS NOT NULL
                  AND "lineValue" IS NOT NULL
                  AND "homeTeam" = %s
                  AND "awayTeam" = %s
                  AND "gameDate"::date = %s::date
                ORDER BY ABS("lineValue" - "openingLineValue") DESC
                LIMIT 1
                """,
                (home_team, away_team, game_dt)
            )
            row = cur.fetchone()
            if row and row[0] is not None:
                agg[team]['line_move'] += float(row[0])
                agg[team]['line_move_count'] += 1

    stats_added = 0
    for team, data in agg.items():
        games = data['games']
        if games == 0:
            continue
        cover_rate = data['covers'] / data['cover_games'] if data['cover_games'] > 0 else None
        avg_margin = data['margin'] / games
        avg_line_move = data['line_move'] / data['line_move_count'] if data['line_move_count'] > 0 else 0.0

        for stat_key, val in [
            ('nba_vs_injured_games', games),
            ('nba_vs_injured_cover_rate', cover_rate if cover_rate is not None else 0.0),
            ('nba_vs_injured_margin', avg_margin),
            ('nba_injury_line_move', avg_line_move),
        ]:
            cur.execute(sql_upsert, ('nba', season, game_key, game_date, team, stat_key, float(val)))
            stats_added += 1

    conn.commit()
    cur.close()
    conn.close()
    print(f'✅ NBA injury impact metrics ingested: {stats_added}')


if __name__ == '__main__':
    import sys
    season = int(sys.argv[1]) if len(sys.argv) > 1 else 2024
    ingest_injury_impact(season)
