#!/usr/bin/env python3
"""Focused jackpot + true-MRT scan on live landing (no archive)."""
from __future__ import annotations

import json
from collections import Counter
from datetime import datetime
from pathlib import Path

BASE = Path(__file__).resolve().parents[1] / "logs"

# Failed JP ~22:30 EDT, success ~22:43 EDT → UTC+4
FOCUS0 = datetime.fromisoformat("2026-08-04T02:25:00+00:00")
FOCUS1 = datetime.fromisoformat("2026-08-04T02:50:00+00:00")
N0 = datetime.fromisoformat("2026-08-03T23:00:00+00:00")
N1 = datetime.fromisoformat("2026-08-04T12:00:00+00:00")

INTEREST = (
    "fireworks",
    "jackpot",
    "jpot",
    "skill",
    "early_win_phase",
    "early_win_slot_award",
    "early_win_slot_fire",
    "mrt_risk_late",
    "mrt_risk_missing",
    "mrt_risk_await",
    "x9_no_local",
    "lab_",
    "trunk_round_stale",
    "inject_failed",
    "uartd_",
    "edge_",
    "enroll",
    "session_start",
    "session_end",
    "eth_port",
    "status_0d_synth_fail",
    "progressive",
)


def parse_utc(s):
    if not s:
        return None
    try:
        return datetime.fromisoformat(s.replace("Z", "+00:00"))
    except Exception:
        return None


def files(pos):
    d = BASE / str(pos) / "data"
    return sorted(d.glob("events.jsonl*")) if d.is_dir() else []


def interesting(ev: str) -> bool:
    el = ev.lower()
    return any(k in el for k in INTEREST)


def scan_focus(pos: int):
    hits = []
    true_mrt = Counter()
    fireworks = []
    jpotish = []
    session = []
    for fp in files(pos):
        with open(fp, encoding="utf-8", errors="replace") as f:
            for line in f:
                try:
                    e = json.loads(line)
                except Exception:
                    continue
                t = parse_utc(e.get("utc"))
                if t is None or not (FOCUS0 <= t <= FOCUS1):
                    continue
                ev = e.get("ev") or ""
                if ev in (
                    "mrt_risk_late_0d_after_x1",
                    "mrt_risk_missing_x1",
                    "mrt_risk_await_0d_abandon",
                    "x9_no_local_x1",
                ):
                    true_mrt[ev] += 1
                    hits.append(e)
                if "fireworks" in ev.lower() or ev.startswith("fireworks"):
                    fireworks.append(e)
                    hits.append(e)
                if any(
                    x in ev.lower()
                    for x in (
                        "jpot",
                        "jackpot",
                        "skill",
                        "early_win_slot_award",
                        "early_win_phase1",
                        "early_win_phase2",
                    )
                ):
                    jpotish.append(e)
                    hits.append(e)
                if interesting(ev) and ev not in (
                    "progressive_0a_csv_update",
                    "early_win_slot_wager_store",
                    "early_win_slot_skip",
                    "mrt_peer_x1_in_echo",
                    "mrt_risk_arm_skip",
                    "mrt_x9_inject_diag",
                    "status_0d_synth_trigger",
                    "status_0d_synth_skip",
                    "status_0d_synth_done",
                    "status_0d_synth_built",
                    "status_0d_synth_immediate",
                    "mrt_x1_after_x9",
                    "mrt_x1_inferred_no_x9_retry",
                ):
                    # keep high signal
                    if any(
                        x in ev
                        for x in (
                            "fireworks",
                            "jpot",
                            "jackpot",
                            "skill",
                            "award",
                            "late_0d",
                            "missing",
                            "fail",
                            "session",
                            "stale",
                            "uartd",
                            "lab_",
                        )
                    ):
                        hits.append(e)
                if ev == "session_start":
                    session.append(e)
    return {
        "true_mrt": dict(true_mrt),
        "fireworks_n": len(fireworks),
        "jpotish_n": len(jpotish),
        "fireworks": fireworks,
        "jpotish": jpotish,
        "hits": hits,
        "sessions": session,
    }


def summarize_event(e):
    keys = (
        "utc",
        "ev",
        "tid",
        "game",
        "msg",
        "reason",
        "where",
        "trigger",
        "amount",
        "win_usd",
        "jpot_amount",
        "qualifies",
        "source",
        "channel",
        "eth_port",
        "play_sequence",
        "parser_build",
        "message",
    )
    return {k: e.get(k) for k in keys if e.get(k) is not None}


def night_stats(pos: int):
    """True-MRT + hub/star crumbs for overnight."""
    c = Counter()
    lab = Counter()
    stale_lab = 0
    stale_other = 0
    eth_rx_lab_msg = Counter()
    for fp in files(pos):
        with open(fp, encoding="utf-8", errors="replace") as f:
            for line in f:
                try:
                    e = json.loads(line)
                except Exception:
                    continue
                t = parse_utc(e.get("utc"))
                if t is None or not (N0 <= t <= N1):
                    continue
                ev = e.get("ev") or ""
                tid = str(e.get("tid") or "")
                is_lab = len(tid) == 4 and tid.upper().startswith("E0")
                if ev in (
                    "mrt_risk_late_0d_after_x1",
                    "mrt_risk_missing_x1",
                    "mrt_risk_await_0d_abandon",
                    "x9_no_local_x1",
                ):
                    c[ev] += 1
                if ev == "trunk_round_stale_abandon":
                    if is_lab:
                        stale_lab += 1
                        lab[f"stale:{tid}"] += 1
                    else:
                        stale_other += 1
                if is_lab and ev in (
                    "eth_rx",
                    "eth_tx",
                    "packet_complete",
                    "lab_gameplay_synth_wager",
                    "lab_gameplay_synth_ack",
                ):
                    lab[f"{ev}:{e.get('msg')}"] += 1
                if is_lab and ev == "eth_rx":
                    eth_rx_lab_msg[str(e.get("msg"))] += 1
                if "fireworks" in ev.lower():
                    c[f"fw:{ev}"] += 1
                if "jpot" in ev.lower() or "jackpot" in ev.lower():
                    c[f"jp:{ev}"] += 1
    return {
        "true_mrt_and_jp": dict(c),
        "stale_lab": stale_lab,
        "stale_other": stale_other,
        "lab_top": lab.most_common(20),
        "lab_eth_rx_msg": eth_rx_lab_msg.most_common(10),
    }


def main():
    print("FOCUS", FOCUS0, "→", FOCUS1, "(EDT ~22:25–22:50)")
    for pos in (1, 11, 5, 51, 3, 31):
        r = scan_focus(pos)
        print(f"\n======== seat {pos} ========")
        print("true_mrt_window", r["true_mrt"])
        print("fireworks_n", r["fireworks_n"], "jpotish_n", r["jpotish_n"])
        print("sessions", [summarize_event(s) for s in r["sessions"][:3]])
        print("--- fireworks ---")
        for e in r["fireworks"][:30]:
            print(summarize_event(e))
        print("--- jpotish / skill / awards ---")
        for e in r["jpotish"][:40]:
            print(summarize_event(e))
        # unique evs in hits
        evc = Counter((e.get("ev") for e in r["hits"]))
        print("hit_ev_counts", dict(evc.most_common(25)))

    print("\n======== NIGHT STAR/true-MRT seats 1-5 + hub(3) ========")
    for pos in (1, 2, 3, 4, 5, 11, 21, 31, 41, 51):
        r = night_stats(pos)
        print(f"\nseat{pos}: {r['true_mrt_and_jp']}")
        print(
            f"  stale lab/other={r['stale_lab']}/{r['stale_other']} lab_top={r['lab_top'][:8]}"
        )
        if r["lab_eth_rx_msg"]:
            print(f"  lab eth_rx msgs={r['lab_eth_rx_msg']}")


if __name__ == "__main__":
    main()
