"""
KALSHIBOT AUTOMATED — LIVE ANALYZER
Run this anytime to see a full breakdown of bot performance.
Usage: python C:\kalshibot\Automated\tracker\analyze.py
"""
import json, os, datetime
from collections import defaultdict

ANALYTICS_PATH  = r"C:\kalshibot\Automated\trade_analytics.json"
PAPER_LOG_PATH  = r"C:\kalshibot\Automated\paper_log.json"
BOT_STATE_PATH  = r"C:\kalshibot\Automated\bot_state.json"
PERF_PATH       = r"C:\kalshibot\Automated\tracker\signal_performance.json"
PHASE_PERF_PATH = r"C:\kalshibot\Automated\tracker\phase_performance.json"

def load(path, default):
    try:
        with open(path) as f: return json.load(f)
    except: return default

def pct(n, d): return f"{n/d*100:.1f}%" if d > 0 else "---"
def avg(lst):  return sum(lst)/len(lst) if lst else 0

def run():
    analytics = load(ANALYTICS_PATH, [])
    paper_log  = load(PAPER_LOG_PATH, {})
    bot_state  = load(BOT_STATE_PATH, {})
    trades     = paper_log.get("trades", []) if isinstance(paper_log, dict) else []
    exits      = [t for t in analytics if t.get("event") == "exit"]
    entries    = [t for t in analytics if t.get("event") == "entry"]

    print("\n" + "="*70)
    print("  KALSHIBOT AUTOMATED — LIVE ANALYSIS")
    print(f"  {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("="*70)

    # ── Live state ──────────────────────────────────────────────────────────
    if bot_state:
        bal   = bot_state.get("balance", 0)
        start = bot_state.get("starting_balance", 500)
        btc   = bot_state.get("btc_price", 0)
        pnl   = bal - start
        open_pos = bot_state.get("open_positions", [])
        print(f"\n  LIVE STATE")
        print(f"  Balance   : ${bal:.2f}  (started ${start:.2f}, P&L: ${pnl:+.2f} / {pnl/start*100:+.1f}%)")
        print(f"  BTC Price : ${btc:,.2f}")
        print(f"  Open Pos  : {len(open_pos)}")
        print(f"  Score     : {bot_state.get('confidence_score', 0)}  {bot_state.get('score_breakdown','')}")

    # ── Overall stats ────────────────────────────────────────────────────────
    if not exits:
        print("\n  No completed trades yet. Bot is gathering data...")
        return

    wins   = [t for t in exits if t.get("outcome") == "WIN"]
    losses = [t for t in exits if t.get("outcome") == "LOSS"]
    pnls   = [t.get("pnl", 0) for t in exits]
    total_pnl = sum(pnls)

    print(f"\n  OVERALL  ({len(exits)} completed trades)")
    print(f"  Win Rate  : {pct(len(wins), len(exits))}  ({len(wins)}W / {len(losses)}L)")
    print(f"  Total P&L : ${total_pnl:+.4f}")
    print(f"  Avg/trade : ${avg(pnls):+.4f}")
    if wins:   print(f"  Avg Win   : ${avg([t['pnl'] for t in wins]):+.4f}")
    if losses: print(f"  Avg Loss  : ${avg([t['pnl'] for t in losses]):+.4f}")

    # ── Signal combo breakdown ───────────────────────────────────────────────
    print(f"\n  BY SIGNAL COMBO")
    combo_map = defaultdict(lambda: {"wins": 0, "total": 0, "pnl": 0.0})
    for t in exits:
        e, l, m = t.get("exp_score",0), t.get("lag_score",0), t.get("mom_score",0)
        parts = []
        if e > 0: parts.append("EXP")
        if l > 0: parts.append("LAG")
        if m > 0: parts.append("MOM")
        combo = "+".join(parts) if parts else "NONE"
        combo_map[combo]["total"] += 1
        combo_map[combo]["pnl"]   += t.get("pnl", 0)
        if t.get("outcome") == "WIN": combo_map[combo]["wins"] += 1
    for combo, d in sorted(combo_map.items(), key=lambda x: -x[1]["total"]):
        wr   = pct(d["wins"], d["total"])
        print(f"  {combo:<20} {d['total']:>4} trades  WR:{wr:>7}  P&L:${d['pnl']:+.2f}")

    # ── Phase breakdown ──────────────────────────────────────────────────────
    print(f"\n  BY PHASE (time remaining when entered)")
    phase_map = defaultdict(lambda: {"wins": 0, "total": 0, "pnl": 0.0})
    for t in exits:
        secs = t.get("secs_left", 0)
        if   secs > 480: phase = "early (>8min)"
        elif secs > 240: phase = "mid   (4-8min)"
        elif secs > 90:  phase = "near  (1.5-4min)"
        else:            phase = "late  (<1.5min)"
        phase_map[phase]["total"] += 1
        phase_map[phase]["pnl"]   += t.get("pnl", 0)
        if t.get("outcome") == "WIN": phase_map[phase]["wins"] += 1
    phase_order = ["early (>8min)", "mid   (4-8min)", "near  (1.5-4min)", "late  (<1.5min)"]
    for phase in phase_order:
        d = phase_map[phase]
        if d["total"] == 0: continue
        wr = pct(d["wins"], d["total"])
        print(f"  {phase:<22} {d['total']:>4} trades  WR:{wr:>7}  P&L:${d['pnl']:+.2f}")

    # ── Score tier breakdown ─────────────────────────────────────────────────
    print(f"\n  BY SCORE BUCKET")
    score_map = defaultdict(lambda: {"wins": 0, "total": 0, "pnl": 0.0})
    for t in exits:
        sc = t.get("confidence_score", 0)
        if   sc >= 55: bucket = "55+  (very strong)"
        elif sc >= 40: bucket = "40-54 (strong)"
        elif sc >= 25: bucket = "25-39 (HIGH)"
        elif sc >= 18: bucket = "18-24 (MED-HIGH)"
        else:          bucket = "12-17 (MEDIUM)"
        score_map[bucket]["total"] += 1
        score_map[bucket]["pnl"]   += t.get("pnl", 0)
        if t.get("outcome") == "WIN": score_map[bucket]["wins"] += 1
    for bucket, d in sorted(score_map.items(), key=lambda x: -x[1]["total"]):
        wr = pct(d["wins"], d["total"])
        print(f"  {bucket:<24} {d['total']:>4} trades  WR:{wr:>7}  P&L:${d['pnl']:+.2f}")

    # ── Hour of day breakdown ────────────────────────────────────────────────
    print(f"\n  BY HOUR (top 5 most active)")
    hour_map = defaultdict(lambda: {"wins": 0, "total": 0, "pnl": 0.0})
    for t in exits:
        h = t.get("hour", -1)
        hour_map[h]["total"] += 1
        hour_map[h]["pnl"]   += t.get("pnl", 0)
        if t.get("outcome") == "WIN": hour_map[h]["wins"] += 1
    top_hours = sorted(hour_map.items(), key=lambda x: -x[1]["total"])[:5]
    for h, d in top_hours:
        wr = pct(d["wins"], d["total"])
        print(f"  {h:02d}:xx   {d['total']:>4} trades  WR:{wr:>7}  P&L:${d['pnl']:+.2f}")

    # ── Exit reason breakdown ────────────────────────────────────────────────
    print(f"\n  BY EXIT REASON")
    reason_map = defaultdict(lambda: {"wins": 0, "total": 0, "pnl": 0.0})
    for t in exits:
        r = t.get("exit_reason", "?")
        if   "TARGET" in str(r): key = "TARGET hit"
        elif "STOP"   in str(r): key = "STOP hit"
        elif "TIME"   in str(r): key = "TIME expiry"
        else:                    key = str(r)[:20]
        reason_map[key]["total"] += 1
        reason_map[key]["pnl"]   += t.get("pnl", 0)
        if t.get("outcome") == "WIN": reason_map[key]["wins"] += 1
    for reason, d in sorted(reason_map.items(), key=lambda x: -x[1]["total"]):
        wr = pct(d["wins"], d["total"])
        print(f"  {reason:<22} {d['total']:>4} trades  WR:{wr:>7}  P&L:${d['pnl']:+.2f}")

    # ── Road to 50 wins ──────────────────────────────────────────────────────
    total_wins = len(wins)
    needed     = max(0, 50 - total_wins)
    print(f"\n  ROAD TO 50 WINS")
    print(f"  Wins so far  : {total_wins}")
    print(f"  Still needed : {needed}")
    if total_wins > 0:
        proj_rate = len(wins) / len(exits)
        trades_needed = int(needed / proj_rate) if proj_rate > 0 else "?"
        print(f"  At {proj_rate*100:.0f}% WR, need ~{trades_needed} more total trades to get {needed} more wins")

    # ── Save structured performance data ────────────────────────────────────
    perf = {"generated": str(datetime.datetime.now()), "combos": dict(combo_map),
            "phases": dict(phase_map), "scores": dict(score_map)}
    with open(PERF_PATH, "w") as f: json.dump(perf, f, indent=2, default=str)
    print(f"\n  Performance data saved to tracker/signal_performance.json")
    print("="*70 + "\n")

if __name__ == "__main__":
    run()
