"""Analyse approfondie des opportunités ratées aujourd'hui."""
import json
import datetime

cutoff = datetime.datetime(2026, 3, 8, 7, 0, 0)

with open('espion_opportunities.json', encoding='utf-8') as f:
    opps = json.load(f)

with open('espion_history.json', encoding='utf-8') as f:
    trades = json.load(f)

# Index les trades exécutés par symbole+heure pour corréler
executed_windows = {}  # symbol -> list of (entry_time, exit_time, pnl_pct)
for t in trades:
    sym = t.get('symbol')
    if not sym:
        continue
    etime = t.get('entry_time') or t.get('timestamp')
    xtime = t.get('exit_time')
    pnl = t.get('pnl_pct')
    if etime:
        try:
            edt = datetime.datetime.fromisoformat(str(etime).replace('Z', ''))
            xdt = datetime.datetime.fromisoformat(str(xtime).replace('Z', '')) if xtime else None
            executed_windows.setdefault(sym, []).append((edt, xdt, pnl))
        except Exception:
            pass

# Classer toutes les opps du jour par raison de rejet
today_opps = []
for o in opps:
    ts = o.get('timestamp')
    if not ts:
        continue
    try:
        dt = datetime.datetime.fromisoformat(str(ts).replace('Z', ''))
        if dt >= cutoff:
            today_opps.append((dt, o))
    except Exception:
        pass

today_opps.sort(key=lambda x: x[0])
total = len(today_opps)
executed = sum(1 for _, o in today_opps if o.get('executed'))
rejected = total - executed

# Résumé raisons de rejet
reasons = {}
for _, o in today_opps:
    if not o.get('executed'):
        r = o.get('reason', 'unknown')
        key = r.split('(')[0].strip().split(',')[0].strip()
        reasons[key] = reasons.get(key, 0) + 1

print(f"=== RESUME JOURNEE {datetime.date.today()} ===")
print(f"Total detections: {total} | Exécutés: {executed} | Rejetés: {rejected}")
print()
print("Raisons de rejet (résumées):")
for r, c in sorted(reasons.items(), key=lambda x: -x[1]):
    print(f"  {c:4d}x  {r}")

# Chercher les patterns rejetés avec des indicateurs forts
print()
print("=== OPPORTUNITES REJETEES AVEC SIGNAUX FORTS ===")
print("(surge >= 2.0% OU vol >= 5x OU already_pumped avec surge fort)")
print()

strong_missed = []
for dt, o in today_opps:
    if o.get('executed'):
        continue
    ind = o.get('indicators', {})
    surge = ind.get('surge_strength', ind.get('change_1scan', 0)) or 0
    vol = ind.get('volume_spike', ind.get('vol_ratio', 0)) or 0
    reason = o.get('reason', '')
    score = o.get('score', 0) or 0

    # Signaux forts = surge > 2% OU vol > 5x OU score > 60
    if surge >= 2.0 or vol >= 5.0 or score >= 60:
        strong_missed.append((dt, o, surge, vol, score, reason))

strong_missed.sort(key=lambda x: -(x[4]))  # sort by score desc

for dt, o, surge, vol, score, reason in strong_missed:
    sym = o.get('symbol', '?')
    pat = o.get('pattern', '?')
    hour = dt.strftime("%H:%M")
    # Chercher si ce coin a eu un trade bien après (pump raté)
    related = executed_windows.get(sym, [])
    trade_note = ''
    for edt, xdt, pnl in related:
        delta = (edt - dt).total_seconds() / 60
        if 0 < delta < 60:
            trade_note = f'  → bot a acheté {delta:.0f}min après: pnl={pnl}'
            break
    print(f"  {hour}  {sym:<14s}  score={score:<6.1f}  surge={surge:.2f}%  vol={vol:.1f}x  pat={pat}")
    print(f"         raison: {reason[:100]}{trade_note}")

# Analyser specifically les "already_pumped" avec gros surge
print()
print("=== ANALYSE already_pumped_24h ===")
print("(cibles rejetées pour déjà pumpé mais avec signal fort ce matin)")
pumped_strong = []
for dt, o in today_opps:
    if o.get('executed'):
        continue
    reason = o.get('reason', '')
    if 'already_pumped' not in reason:
        continue
    ind = o.get('indicators', {})
    surge = ind.get('surge_strength', ind.get('change_1scan', 0)) or 0
    vol = ind.get('volume_spike', ind.get('vol_ratio', 0)) or 0
    # Extraire le % 24h depuis la raison
    pct_24h = 0
    try:
        pct_24h = float(reason.split('already_pumped_24h(')[1].split('%')[0])
    except Exception:
        pass
    score = o.get('score', 0) or 0
    if surge >= 1.5 and vol >= 2.0:
        pumped_strong.append((dt, o, surge, vol, pct_24h, score))

pumped_strong.sort(key=lambda x: -x[2])
print(f"Rejetés 'already_pumped' avec surge>=1.5% ET vol>=2x: {len(pumped_strong)}")
for dt, o, surge, vol, pct_24h, score in pumped_strong[:20]:
    sym = o.get('symbol', '?')
    pat = o.get('pattern', '?')
    hour = dt.strftime("%H:%M")
    print(f"  {hour}  {sym:<14s}  surge={surge:.2f}%  vol={vol:.1f}x  24h={pct_24h:.0f}%  score={score:.0f}  pat={pat}")

# Stats générales sur la qualité du filtre already_pumped
print()
print("=== SEUIL already_pumped_24h: est-il trop restrictif ? ===")
pct_vals = []
for dt, o in today_opps:
    reason = o.get('reason', '')
    if 'already_pumped' not in reason:
        continue
    try:
        pct = float(reason.split('already_pumped_24h(')[1].split('%')[0])
        pct_vals.append(pct)
    except Exception:
        pass

if pct_vals:
    pct_vals.sort()
    n = len(pct_vals)
    print(f"  Nb rejetés par already_pumped: {n}")
    print(f"  Min: {pct_vals[0]:.1f}%  Max: {pct_vals[-1]:.1f}%")
    print(f"  Médiane: {pct_vals[n//2]:.1f}%")
    breakpoints = [50, 60, 70, 80, 100, 120, 150]
    for bp in breakpoints:
        cnt = sum(1 for p in pct_vals if p < bp)
        print(f"  < {bp}%: {cnt}x ({100*cnt//n}%)")

# Analyse du seuil vol_low
print()
print("=== SEUIL vol_low: est-il trop restrictif ? ===")
vol_thresholds = {}
for dt, o in today_opps:
    if o.get('executed'):
        continue
    reason = o.get('reason', '')
    if 'vol_low' not in reason:
        continue
    ind = o.get('indicators', {})
    surge = ind.get('surge_strength', ind.get('change_1scan', 0)) or 0
    # Extraire vol actual et seuil
    try:
        part = reason.split('vol_low(')[1].split(')')[0]  # e.g. "0.6x<1.0x"
        actual = float(part.split('x')[0])
        threshold = float(part.split('<')[1].replace('x', ''))
        key = f"seuil_{threshold}x"
        if key not in vol_thresholds:
            vol_thresholds[key] = {'count': 0, 'surge_vals': []}
        vol_thresholds[key]['count'] += 1
        vol_thresholds[key]['surge_vals'].append(surge)
    except Exception:
        pass

for k, v in sorted(vol_thresholds.items()):
    surges = v['surge_vals']
    avg = sum(surges) / len(surges) if surges else 0
    strong = sum(1 for s in surges if s >= 1.5)
    print(f"  {k}: {v['count']}x rejetés | surge moyen={avg:.2f}% | surge>=1.5%: {strong}x")
