"""
Profili arbitro (Premier League): severità, cartellini, falli, "lascia giocare".

Per ogni arbitro con almeno --min-matches partite:
  - gialli/partita, rossi/partita, falli fischiati/partita
  - cartellini per falllo (severità a parità di fischi)
  - bias casa: differenza gialli ospiti - gialli casa vs media lega

Include un test di AFFIDABILITÀ split-half: dividiamo le partite di ogni
arbitro in due metà (alternate cronologicamente) e correliamo i gialli/partita
tra le due metà. Correlazione alta = la severità è un tratto stabile e
predittivo; vicina a zero = è rumore e non va usata in un modello.

Uso:
    python scripts/referee_profiles.py
    python scripts/referee_profiles.py --min-matches 50

Output: data/processed/referee_profiles.csv
"""

import argparse
import sys
from pathlib import Path

import numpy as np
import pandas as pd
import pymysql

import config

PROJECT_ROOT = Path(__file__).resolve().parent.parent
OUT_PATH = PROJECT_ROOT / "data" / "processed" / "referee_profiles.csv"


def load(args) -> pd.DataFrame:
    conn = pymysql.connect(host=args.host, port=args.port, user=args.user,
                           password=args.password, database="tigertips")
    df = pd.read_sql("""
        SELECT m.referee, m.match_date,
               m.home_yellow, m.away_yellow, m.home_red, m.away_red,
               m.home_fouls, m.away_fouls
        FROM matches m
        JOIN leagues l ON l.id = m.league_id
        WHERE l.code = %s AND m.referee IS NOT NULL
        ORDER BY m.match_date
    """, conn, params=(args.league,))
    conn.close()
    for c in df.columns.drop(["referee", "match_date"]):
        df[c] = pd.to_numeric(df[c], errors="coerce")
    df["yellows"] = df["home_yellow"] + df["away_yellow"]
    df["reds"] = df["home_red"] + df["away_red"]
    df["fouls"] = df["home_fouls"] + df["away_fouls"]
    return df.dropna(subset=["yellows", "fouls"])


def main() -> int:
    parser = argparse.ArgumentParser(description="Profili arbitro per lega")
    parser.add_argument("--league", default="E0", help="Codice lega (default E0)")
    parser.add_argument("--min-matches", type=int, default=30)
    config.add_db_args(parser)
    args = parser.parse_args()

    df = load(args)
    if df.empty:
        print(f"Nessuna partita con arbitro per la lega {args.league}")
        return 1
    league_avg = df["yellows"].mean()
    print(f"Lega {args.league} | partite analizzate: {len(df)} | media lega: "
          f"{league_avg:.2f} gialli, {df['fouls'].mean():.1f} falli a partita\n")

    prof = df.groupby("referee").agg(
        partite=("yellows", "size"),
        gialli_pg=("yellows", "mean"),
        rossi_pg=("reds", "mean"),
        falli_pg=("fouls", "mean"),
        gialli_casa=("home_yellow", "mean"),
        gialli_ospiti=("away_yellow", "mean"),
    )
    prof["cartellini_per_fallo"] = (prof["gialli_pg"] + prof["rossi_pg"]) / prof["falli_pg"]
    prof["bias_casa"] = prof["gialli_ospiti"] - prof["gialli_casa"]
    prof = prof[prof["partite"] >= args.min_matches].sort_values("gialli_pg", ascending=False)

    print(f"=== Profili ({len(prof)} arbitri con >= {args.min_matches} partite) ===")
    print(f"{'Arbitro':<16}{'n':>5}{'gialli':>8}{'rossi':>7}{'falli':>7}"
          f"{'cart/fallo':>11}{'bias osp.':>10}")
    for name, r in prof.iterrows():
        print(f"{name:<16}{r['partite']:>5.0f}{r['gialli_pg']:>8.2f}"
              f"{r['rossi_pg']:>7.2f}{r['falli_pg']:>7.1f}"
              f"{r['cartellini_per_fallo']:>11.3f}{r['bias_casa']:>+10.2f}")

    spread = prof["gialli_pg"].max() - prof["gialli_pg"].min()
    print(f"\nSpread severità: {prof['gialli_pg'].min():.2f} -> "
          f"{prof['gialli_pg'].max():.2f} gialli/partita (delta {spread:.2f})")

    # --- Test di affidabilità split-half ---
    halves = []
    for name, grp in df.groupby("referee"):
        if len(grp) < args.min_matches:
            continue
        grp = grp.sort_values("match_date").reset_index(drop=True)
        even, odd = grp.iloc[::2], grp.iloc[1::2]
        halves.append((name, even["yellows"].mean(), odd["yellows"].mean()))
    hdf = pd.DataFrame(halves, columns=["referee", "meta_a", "meta_b"])
    r = float(np.corrcoef(hdf["meta_a"], hdf["meta_b"])[0, 1])
    # Spearman-Brown: affidabilità sul campione completo
    r_full = 2 * r / (1 + r) if r > -1 else float("nan")
    print(f"\nAffidabilità split-half (gialli/partita): r = {r:.3f} "
          f"(Spearman-Brown campione intero: {r_full:.3f})")
    if r > 0.5:
        verdict = "la severità è un TRATTO STABILE: vale la pena modellarla"
    elif r > 0.25:
        verdict = "segnale reale ma moderato: utile con regolarizzazione (shrinkage)"
    else:
        verdict = "quasi tutto rumore: l'identità dell'arbitro aggiunge poco"
    print(f"Verdetto: {verdict}")

    out_path = OUT_PATH.with_name(f"referee_profiles_{args.league}.csv")
    prof.round(3).to_csv(out_path)
    print(f"\nProfili salvati in: {out_path}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
