"""
Full bet breakdown export for the pure Away CLV strategy.
Outputs E:\soccer\bets_full_breakdown.csv with every OOS qualifying bet,
including team names, scores, CLV%, P&L, and running bankroll at 0.10x/0.25x/0.50x Kelly.
"""
import pandas as pd
import numpy as np

START       = 1_000.0
EDGE_THRESH = 0.05
OUT         = r'E:\soccer\bets_full_breakdown.csv'
OOS_SEASONS = ['2122','2223','2324','2425','2526']

seasons = ['1920','2021','2122','2223','2324','2425','2526']
league_names = {
    'E0': 'EPL', 'E1': 'Championship', 'E2': 'League One', 'E3': 'League Two', 'EC': 'Conference',
    'SP1': 'La Liga', 'SP2': 'Segunda',
    'I1': 'Serie A', 'I2': 'Serie B',
    'D1': 'Bundesliga', 'D2': '2.Bundesliga',
    'F1': 'Ligue 1', 'F2': 'Ligue 2',
    'N1': 'Eredivisie',
    'B1': 'Belgian Pro League',
    'P1': 'Primeira Liga',
    'T1': 'Super Lig',
    'G1': 'Greek SL',
    'SC0': 'Scottish Prem', 'SC1': 'Scottish Champ', 'SC2': 'Scottish L1', 'SC3': 'Scottish L2',
}

def remove_margin(h, d, a):
    over = 1/h + 1/d + 1/a
    return 1/h/over, 1/d/over, 1/a/over

# ── Load all data ──────────────────────────────────────────────────────────────
print("Loading data...")
all_dfs = []
for code, name in league_names.items():
    for s in seasons:
        path = f'E:/soccer/league_data/{code}_{s}.csv'
        try:
            d = pd.read_csv(path, encoding='utf-8-sig')
            if len(d) < 10 or 'FTR' not in d.columns or 'B365A' not in d.columns:
                continue
            d = d.dropna(subset=['FTR','B365A','B365H','B365D','PSCH','PSCD','PSCA'])
            if len(d) < 10: continue
            d['Season'] = s
            d['LeagueCode'] = code
            d['LeagueName'] = name
            all_dfs.append(d)
        except:
            pass

df = pd.concat(all_dfs, ignore_index=True)
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True, errors='coerce')
df = df.dropna(subset=['Date']).sort_values('Date').reset_index(drop=True)

tH, tD, tA = zip(*df.apply(lambda r: remove_margin(r['PSCH'],r['PSCD'],r['PSCA']), axis=1))
df = df.copy()
df['p_A'] = pd.Series(tA, index=df.index)
df['PSC_fair_A'] = 1 / df['p_A']
df['edge_A'] = (df['B365A'] - df['PSC_fair_A']) / df['PSC_fair_A']

print(f"  {len(df):,} matches loaded")

# ── Filter to OOS Away CLV bets ─────────────────────────────────────────────
sub = df[(df['Season'].isin(OOS_SEASONS)) & (df['edge_A'] > EDGE_THRESH)].copy()

all_rows = []
for _, r in sub.iterrows():
    b = r['B365A'] - 1
    p = r['p_A']
    fair = r['PSC_fair_A']
    kelly_f = max((p * b - (1 - p)) / b, 0) if b > 0 else 0
    if kelly_f <= 0:
        continue
    clv_pct = (r['B365A'] - fair) / fair * 100
    all_rows.append({
        'date':           r['Date'].strftime('%Y-%m-%d'),
        'season':         r['Season'],
        'league':         r['LeagueName'],
        'league_code':    r['LeagueCode'],
        'home_team':      r.get('HomeTeam', ''),
        'away_team':      r.get('AwayTeam', ''),
        'bet_outcome':    'Away',
        'actual_result':  r['FTR'],
        'home_goals':     int(r['FTHG']) if pd.notna(r.get('FTHG')) else '',
        'away_goals':     int(r['FTAG']) if pd.notna(r.get('FTAG')) else '',
        'won':            int(r['FTR'] == 'A'),
        'odds':           round(r['B365A'], 2),
        'pinnacle_fair':  round(fair, 3),
        'clv_pct':        round(clv_pct, 2),
        'kelly_fraction': round(kelly_f, 4),
        'p_win_pinnacle': round(p, 4),
    })

bets = pd.DataFrame(all_rows).sort_values('date').reset_index(drop=True)
print(f"  {len(bets):,} OOS Away CLV bets")

# ── Add flat stake P&L ────────────────────────────────────────────────────────
bets['flat_pl']        = (bets['odds'] - 1).where(bets['won'] == 1, -1)
bets['flat_pl_cumsum'] = bets['flat_pl'].cumsum()
bets['flat_roi_pct']   = (bets['flat_pl_cumsum'] / (bets.index + 1) * 100).round(2)

# ── Add Kelly bankrolls ───────────────────────────────────────────────────────
for km, label in [(0.10, '010'), (0.25, '025'), (0.50, '050')]:
    bk = START
    stakes, pls, bankrolls = [], [], []
    for _, row in bets.iterrows():
        f = min(row['kelly_fraction'] * km, 0.25)
        stake = bk * f
        pl = stake * (row['odds'] - 1) if row['won'] else -stake
        bk = max(bk + pl, 0)
        stakes.append(round(stake, 2))
        pls.append(round(pl, 2))
        bankrolls.append(round(bk, 2))
    bets[f'k{label}_stake']    = stakes
    bets[f'k{label}_pl']       = pls
    bets[f'k{label}_bankroll'] = bankrolls

# ── Save ──────────────────────────────────────────────────────────────────────
bets.to_csv(OUT, index=False)
print(f"\nSaved {len(bets):,} bets to {OUT}")

# ── Summary ───────────────────────────────────────────────────────────────────
print(f"\n{'='*65}")
print(f"SUMMARY — Pure Away CLV (OOS only)")
print(f"{'='*65}")
print(f"  Date range:   {bets['date'].min()} to {bets['date'].max()}")
print(f"  Total bets:   {len(bets):,}")
print(f"  Win rate:     {bets['won'].mean()*100:.1f}%")
print(f"  Flat ROI:     {bets['flat_pl'].mean()*100:+.2f}% per bet")
print(f"  Total flat:   {bets['flat_pl'].sum():+.2f} units")

print(f"\n  By season:")
for s, grp in bets.groupby('season'):
    print(f"    {s}  n={len(grp):>4}  WR={grp['won'].mean()*100:.1f}%  ROI={grp['flat_pl'].mean()*100:+.1f}%  flat_PL={grp['flat_pl'].sum():+.2f}")

print(f"\n  By league (min 30 bets):")
lg = bets.groupby('league').agg(n=('won','count'), wr=('won','mean'), roi=('flat_pl','mean'), pl=('flat_pl','sum')).reset_index()
lg = lg[lg['n'] >= 30].sort_values('roi', ascending=False)
for _, r in lg.iterrows():
    print(f"    {r['league']:<22} Away   n={int(r['n']):>4}  WR={r['wr']*100:.1f}%  ROI={r['roi']*100:+.1f}%  PL={r['pl']:+.2f}")

print(f"\n  Kelly final bankrolls (from {START:,.0f}):")
for km, label in [(0.10,'010'),(0.25,'025'),(0.50,'050')]:
    final = bets[f'k{label}_bankroll'].iloc[-1]
    print(f"    {km:.2f}x Kelly:  {final:>12,.2f}  ({final/START:.1f}x)")
