"""Why did the TEST (last 40%) segment of the xlow backtest outperform TRAIN?"""
import sys, csv, glob, math
from collections import defaultdict
sys.path.insert(0, r'E:\soccer\research')
import kalshi_only_execution as K

# loader variant that keeps league + side
fixtures = defaultdict(list)
for path in glob.glob(r'E:\soccer\poly_backfill\*_polybackfill.csv'):
    with open(path, newline='', encoding='utf-8') as fh:
        for r in csv.DictReader(fh):
            fixtures[(r.get('game_date'), r.get('league'), r.get('home'), r.get('away'))].append(r)

bets = []
for (gd, lg, h, a), rows in fixtures.items():
    if not gd:
        continue
    pre = sorted([(K._pts(r['timestamp']), r) for r in rows
                  if (r.get('status') or '').upper() == 'PRE' and K._pts(r['timestamp'])],
                 key=lambda t: t[0])
    ftr = K._result(rows)
    if not pre or not ftr:
        continue
    fx = dict(gd=gd, ftr=ftr, pre=[r for _, r in pre])
    b = K.xlow(fx)
    if b:
        px = b['kalshi_ask'] if b['book'] == 'poly' else b['px']   # rerouted execution
        # recover the side: recompute which side fired (max clv) at the firing snapshot
        bets.append(dict(gd=gd, lg=lg, px=px, won=b['won'], book=b['book'], clv=b['clv']))
bets.sort(key=lambda b: b['gd'])
cut = int(len(bets) * 0.6)
segs = {'TRAIN': bets[:cut], 'TEST': bets[cut:]}
print(f"total {len(bets)} | train {cut} ({bets[0]['gd']}..{bets[cut-1]['gd']}) | "
      f"test {len(bets)-cut} ({bets[cut]['gd']}..{bets[-1]['gd']})")

def net(bs): return sum(((1-b['px'])/b['px']) if b['won'] else -1 for b in bs)

for name, bs in segs.items():
    n = len(bs); w = sum(b['won'] for b in bs)
    impl = sum(b['px'] for b in bs)
    avg_px = impl / n
    print(f"\n=== {name}: n={n} {w}W  WR={w/n*100:.1f}% impl={impl/n*100:.1f}% "
          f"gap={(w-impl)/n*100:+.1f}pp  net={net(bs):+.1f}u  avg_px={avg_px:.3f}")
    # by league
    by = defaultdict(list)
    for b in bs: by[b['lg']].append(b)
    for lg, xs in sorted(by.items(), key=lambda kv: -abs(net(kv[1]))):
        wl = sum(x['won'] for x in xs); im = sum(x['px'] for x in xs)
        print(f"  {lg:5s} n={len(xs):3d} {wl:2d}W (impl {im:.1f})  net={net(xs):+7.2f}u")
    # by cheap book
    for bk in ('kalshi', 'poly'):
        xs = [b for b in bs if b['book'] == bk]
        if xs: print(f"  book={bk:6s} n={len(xs):3d}  net={net(xs):+7.2f}u  WR={sum(x['won'] for x in xs)/len(xs)*100:.1f}%")
    # price buckets
    for lo, hi in ((0, 0.15), (0.15, 0.25), (0.25, 0.40), (0.40, 1.0)):
        xs = [b for b in bs if lo <= b['px'] < hi]
        if xs:
            wl = sum(x['won'] for x in xs); im = sum(x['px'] for x in xs)
            print(f"  px[{lo:.2f},{hi:.2f}) n={len(xs):3d} {wl:2d}W (impl {im:.1f})  net={net(xs):+7.2f}u")
    # day concentration
    days = defaultdict(list)
    for b in bs: days[b['gd']].append(b)
    day_nets = sorted(((net(xs), d) for d, xs in days.items()), reverse=True)
    top3 = sum(x for x, _ in day_nets[:3])
    print(f"  top-3 days contribute {top3:+.1f}u of {net(bs):+.1f}u  "
          f"({[d for _, d in day_nets[:3]]})")
    # by month
    mon = defaultdict(list)
    for b in bs: mon[b['gd'][:7]].append(b)
    for m, xs in sorted(mon.items()):
        print(f"  {m}: n={len(xs):3d}  net={net(xs):+7.2f}u")
