#!/usr/bin/env python3
"""Collect every finished clip run into one index the beta viewer can switch on."""

from __future__ import annotations

import argparse
import json
from pathlib import Path

TITLES = {
    "load-0800": "上片 08:00–12:00 (早班)",
    "load-1300": "上片 13:00–17:00 (午班)",
    "load-1730": "上片 17:30–21:30 (晚班)",
    "load-2200": "上片 22:00–02:00 (夜班)",
}
T0 = {"load-0800": 8 * 3600, "load-1300": 13 * 3600, "load-1730": 17 * 3600 + 1800, "load-2200": 22 * 3600}


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--runs-dir", default="runs")
    ap.add_argument("--metrics-dir", default="metrics")
    ap.add_argument("--furnace", default="data/furnace_20260617.json")
    ap.add_argument("--out", required=True)
    args = ap.parse_args()

    fur = json.loads(Path(args.furnace).read_text(encoding="utf-8"))
    clips = []
    for cid in TITLES:
        run = Path(args.runs_dir) / cid
        s = run / "summary_v2.json"
        if not s.exists():
            continue
        summary = json.loads(s.read_text(encoding="utf-8"))
        tr = run / "track_report.json"
        track = json.loads(tr.read_text(encoding="utf-8")) if tr.exists() else {}
        pl = Path(args.metrics_dir) / f"{cid}_phaselock.json"
        phase = json.loads(pl.read_text(encoding="utf-8")) if pl.exists() else {}
        hours = summary["n_frames"] / 3600.0
        clips.append(
            {
                "id": cid,
                "title": TITLES[cid],
                "wall_t0_sec": T0[cid],
                "dir": f"./{cid}/",
                "n_frames": summary["n_frames"],
                "hours": round(hours, 2),
                "n_cycles": summary["n_cycles"],
                "cycles_per_hour": round(summary["n_cycles"] / hours, 1) if hours else None,
                "furnace_charges": fur["per_clip"].get(cid, {}).get("n_batches"),
                "work_person_sec": summary["work_person_sec"],
                "wait_person_sec": summary["wait_person_sec"],
                "offstation_person_sec": summary.get("offstation_person_sec"),
                "work_share": round(
                    summary["work_person_sec"] / max(summary["work_person_sec"] + summary["wait_person_sec"], 1), 3
                ),
                "n_tracks": summary["n_unique_tracks"],
                "median_track_len_sec": track.get("median_track_len_sec"),
                "phase_R": phase.get("phase_R"),
                "rayleigh_p": phase.get("rayleigh_p"),
                "locked": phase.get("locked"),
                "mean_offset_sec": phase.get("mean_offset_sec_after_charge"),
                "circular_sd_sec": phase.get("circular_sd_sec"),
                "count_error_pct": phase.get("count_error_pct"),
                "control_fp_rate": phase.get("control_false_positive_rate"),
            }
        )

    out = {
        "generated_for": "beta review",
        "furnace_source": fur["source"],
        "furnace_batches_total": fur["n_batches"],
        "clips": clips,
        "totals": {
            "hours": round(sum(c["hours"] for c in clips), 1),
            "cycles": sum(c["n_cycles"] for c in clips),
            "furnace_charges": sum(c["furnace_charges"] or 0 for c in clips),
            "work_person_hours": round(sum(c["work_person_sec"] for c in clips) / 3600, 1),
            "wait_person_hours": round(sum(c["wait_person_sec"] for c in clips) / 3600, 1),
        },
    }
    Path(args.out).write_text(json.dumps(out, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(f"{len(clips)} clips -> {args.out}")
    for c in clips:
        print(
            f"  {c['id']:<12} {c['hours']}h  cycles={c['n_cycles']:>3} vs furnace={c['furnace_charges']:>3}"
            f"  ({c['count_error_pct']}%)  R={c['phase_R']}  locked={c['locked']}  tracks={c['n_tracks']}"
        )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
