"""
Scarica lo storico xG (expected goals) da Understat per le leghe coperte:
Premier League, La Liga, Bundesliga, Serie A, Ligue 1 (niente Serie B).

I dati arrivano dall'endpoint JSON interno del sito
(GET /getLeagueData/<lega>/<anno>, lo stesso usato dalla pagina web).

Uso:
    python scripts/download_xg.py
    python scripts/download_xg.py --seasons 2024 2025   # solo alcune stagioni

Output:
    data/raw/understat/<league>_<year>.json   (cache)
    data/processed/xg.csv                     (tutte le partite con xG)
"""

import argparse
import json
import sys
import time
from pathlib import Path

import pandas as pd
import requests

PROJECT_ROOT = Path(__file__).resolve().parent.parent
RAW_DIR = PROJECT_ROOT / "data" / "raw" / "understat"
OUT_PATH = PROJECT_ROOT / "data" / "processed" / "xg.csv"

# nome Understat -> codice lega football-data
LEAGUES = {
    "EPL": "E0",
    "La_liga": "SP1",
    "Bundesliga": "D1",
    "Serie_A": "I1",
    "Ligue_1": "F1",
}

# anno di inizio stagione: 2017 = stagione 2017/18
DEFAULT_SEASONS = [str(y) for y in range(2017, 2026)]

HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                         "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"}


def fetch_league_season(league: str, year: str, force: bool = False) -> list | None:
    RAW_DIR.mkdir(parents=True, exist_ok=True)
    cache = RAW_DIR / f"{league}_{year}.json"
    if cache.exists() and not force:
        print(f"  [cache] {cache.name}")
        return json.loads(cache.read_text(encoding="utf-8"))

    url = f"https://understat.com/getLeagueData/{league}/{year}"
    headers = HEADERS | {"X-Requested-With": "XMLHttpRequest",
                         "Referer": f"https://understat.com/league/{league}/{year}"}
    for attempt in range(3):
        try:
            resp = requests.get(url, headers=headers, timeout=30)
            resp.raise_for_status()
            data = resp.json()["dates"]
            cache.write_text(json.dumps(data), encoding="utf-8")
            print(f"  [ok]    {league}/{year}: {len(data)} partite")
            time.sleep(0.7)  # cortesia verso il server
            return data
        except requests.RequestException as exc:
            print(f"  [retry {attempt + 1}/3] {url}: {exc}")
            time.sleep(3 * (attempt + 1))
    print(f"  [FAIL]  {url}")
    return None


def main() -> int:
    parser = argparse.ArgumentParser(description="Scarica xG storico da Understat")
    parser.add_argument("--seasons", nargs="+", default=DEFAULT_SEASONS,
                        help="Anni di inizio stagione, es. 2024 per 2024/25")
    parser.add_argument("--force", action="store_true", help="Ignora la cache")
    args = parser.parse_args()

    rows = []
    for league, code in LEAGUES.items():
        for year in args.seasons:
            data = fetch_league_season(league, year, force=args.force)
            if data is None:
                continue
            for match in data:
                if not match.get("isResult"):
                    continue
                rows.append({
                    "league": code,
                    "datetime": match["datetime"],
                    "home_us": match["h"]["title"],
                    "away_us": match["a"]["title"],
                    "hg": int(match["goals"]["h"]),
                    "ag": int(match["goals"]["a"]),
                    "xg_h": round(float(match["xG"]["h"]), 3),
                    "xg_a": round(float(match["xG"]["a"]), 3),
                })

    if not rows:
        print("Nessun dato scaricato.")
        return 1

    df = pd.DataFrame(rows)
    df["date"] = pd.to_datetime(df["datetime"]).dt.date
    df = df.sort_values(["date", "league"]).reset_index(drop=True)
    OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
    df.to_csv(OUT_PATH, index=False)

    print("\n=== Riepilogo xG ===")
    print(f"Partite totali: {len(df)}")
    for code, grp in df.groupby("league"):
        print(f"  {code:<5} {len(grp):>6}   {grp['date'].min()} -> {grp['date'].max()}")
    print(f"\nSalvato in: {OUT_PATH}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
