#!/usr/bin/env python3
"""Build betting/cfb_historical.json from BallDontLie ncaaf caches.

Inputs:
- data/ncaaf/games.json
- data/ncaaf/odds.json (optional; may be missing depending on API tier)
"""

import json
from pathlib import Path
from typing import Dict, Optional

BASE = Path('/var/www/html/eventheodds/data')
GAMES = BASE / 'ncaaf' / 'games.json'
ODDS = BASE / 'ncaaf' / 'odds.json'
OUT = BASE / 'betting' / 'cfb_historical.json'


def to_float(x) -> Optional[float]:
    if x is None:
        return None
    s = str(x).strip()
    if not s or s.lower() in ('na','nan'):
        return None
    try:
        return float(s)
    except Exception:
        return None


def to_int(x) -> Optional[int]:
    if x is None:
        return None
    s = str(x).strip()
    if not s or s.lower() in ('na','nan'):
        return None
    try:
        return int(float(s))
    except Exception:
        return None


def main():
    if not GAMES.exists():
        raise SystemExit(f"Missing {GAMES}")

    games = json.load(open(GAMES))
    odds_by_game: Dict[int, dict] = {}

    if ODDS.exists():
        odds = json.load(open(ODDS))
        # pick first per game for now
        for o in odds:
            gid = o.get('game_id')
            if gid is None:
                continue
            odds_by_game.setdefault(int(gid), o)

    out = []
    for g in games:
        gid = g.get('id')
        if gid is None:
            continue
        date = (g.get('date') or '')[:10]
        if not date:
            continue

        home = g.get('home_team') or {}
        away = g.get('visitor_team') or {}
        home_name = home.get('full_name') or home.get('name')
        away_name = away.get('full_name') or away.get('name')
        if not home_name or not away_name:
            continue

        hs = g.get('home_score') or 0
        a_s = g.get('away_score') or 0
        if (hs == 0 and a_s == 0):
            continue

        season = g.get('season')
        season_int = int(season) if isinstance(season, int) or (isinstance(season, str) and str(season).isdigit()) else int(date[:4])

        o_raw = odds_by_game.get(int(gid))
        o = {
            'moneylineHome': None,
            'moneylineAway': None,
            'spreadHome': None,
            'spreadAway': None,
            'totalLine': None,
            'source': 'none',
        }
        has_real = False
        if o_raw:
            o['source'] = 'balldontlie'
            o['vendor'] = o_raw.get('vendor')
            o['moneylineHome'] = to_int(o_raw.get('moneyline_home_odds'))
            o['moneylineAway'] = to_int(o_raw.get('moneyline_away_odds'))
            o['spreadHome'] = to_float(o_raw.get('spread_home_value'))
            o['spreadAway'] = to_float(o_raw.get('spread_away_value'))
            o['totalLine'] = to_float(o_raw.get('total_value'))
            has_real = any(o.get(k) is not None for k in ('moneylineHome','moneylineAway','spreadHome','totalLine'))

        margin = hs - a_s
        winner = 'home' if margin > 0 else ('away' if margin < 0 else 'draw')

        out.append({
            'id': f"cfb-{gid}",
            'bdl_game_id': gid,
            'sport': 'cfb',
            'date': date,
            'season': season_int,
            'week': g.get('week'),
            'homeTeam': home_name,
            'awayTeam': away_name,
            'scores': {'homeScore': hs, 'awayScore': a_s},
            'odds': o,
            'hasRealOdds': bool(has_real),
            'result': {'winner': winner, 'margin': margin, 'totalPoints': hs + a_s}
        })

    out.sort(key=lambda x: x.get('date',''))
    OUT.parent.mkdir(parents=True, exist_ok=True)
    json.dump(out, open(OUT,'w'), indent=2)
    real = sum(1 for g in out if g.get('hasRealOdds'))
    print(f"Wrote {OUT} games={len(out)} hasRealOdds={real} ({(real/len(out)*100) if out else 0:.1f}%)")


if __name__ == '__main__':
    main()
