#!/usr/bin/env python3
"""Parse 20260630-recoreds.csv → GT intervals/events for Phase A metrics."""

from __future__ import annotations

import argparse
import csv
import json
import re
from pathlib import Path


PEOPLE = [
    (0, 1, 2, "曾建程", "load"),
    (3, 4, 5, "賴彥碩", "load"),
    (6, 7, 8, "阮文明", "unload"),
    (9, 10, 11, "許信德", "unload"),
]


def parse_clock(s: str) -> int | None:
    s = (s or "").strip()
    if not s or not re.match(r"^\d{1,2}:", s):
        return None
    parts = s.split(":")
    try:
        h, m = int(parts[0]), int(parts[1])
        sec = int(float(parts[2])) if len(parts) > 2 else 0
        return h * 3600 + m * 60 + sec
    except ValueError:
        return None


def parse_dur(s: str) -> int:
    s = (s or "").strip()
    if not s:
        return 0
    parts = s.split(":")
    try:
        nums = [int(float(x)) for x in parts]
    except ValueError:
        return 0
    if len(nums) == 3:
        return nums[0] * 3600 + nums[1] * 60 + nums[2]
    if len(nums) == 2:
        return nums[0] * 60 + nums[1]
    return 0


def classify(action: str) -> str:
    a = action.strip()
    if re.search(r"^等待$|等待前|等待強化|等待進|等待出|走到.*等待|等待上片|等待&", a):
        return "wait_like"
    if "上片" in a and "等待" not in a:
        return "load_cycle"
    if any(k in a for k in ("下片", "收片", "出爐", "搬下放置", "放豆豆")):
        return "unload_like"
    if any(k in a for k in ("搬", "吊", "扶A", "整理玻璃", "整理A", "移車", "駕駛電動")):
        return "handle_glass"
    if any(k in a for k in ("離開", "裝水", "WC", "喝水")):
        return "leave"
    return "other"


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--csv", required=True)
    ap.add_argument("--shift-start", type=int, default=8 * 3600)
    ap.add_argument("--video-t0-wall", type=int, default=8 * 3600)
    ap.add_argument("--window-start", type=int, default=None, help="wall clock sec inclusive")
    ap.add_argument("--window-end", type=int, default=None, help="wall clock sec exclusive")
    ap.add_argument("--out", required=True)
    args = ap.parse_args()

    rows = list(csv.reader(Path(args.csv).read_text(encoding="utf-8-sig").splitlines()))
    events: list[dict] = []
    for row in rows[3:]:
        for a_i, t_i, d_i, name, role in PEOPLE:
            if len(row) <= d_i:
                continue
            act = (row[a_i] or "").strip()
            t = (row[t_i] or "").strip()
            d = (row[d_i] or "").strip()
            if not act:
                continue
            clock = parse_clock(t)
            if clock is None:
                continue
            if args.window_start is not None and clock < args.window_start:
                continue
            if args.window_end is not None and clock >= args.window_end:
                continue
            dur = parse_dur(d)
            cat = classify(act)
            video_t = clock - args.video_t0_wall
            events.append(
                {
                    "person": name,
                    "role": role,
                    "action": act,
                    "category": cat,
                    "priority": 3 if cat in {"load_cycle", "unload_like"} else 2 if cat == "wait_like" else 1 if cat == "handle_glass" else 0,
                    "clock": t,
                    "clock_sec": clock,
                    "dur_sec": dur,
                    "video_t": video_t,
                    "video_t_end": video_t + max(dur, 1),
                }
            )

    intervals = []
    for e in events:
        if e["category"] in {"wait_like", "load_cycle", "unload_like", "handle_glass"}:
            kind = "wait" if e["category"] == "wait_like" else "work"
            intervals.append(
                {
                    "kind": kind,
                    "category": e["category"],
                    "person": e["person"],
                    "role": e["role"],
                    "t0": e["video_t"],
                    "t1": e["video_t_end"],
                    "action": e["action"],
                    "priority": e["priority"],
                }
            )

    cycles = [e for e in events if e["category"] == "load_cycle"]
    out = {
        "source_csv": str(args.csv),
        "video_t0_wall_sec": args.video_t0_wall,
        "window_wall": [args.window_start, args.window_end],
        "n_events": len(events),
        "n_load_cycles": len(cycles),
        "events": events,
        "intervals": intervals,
        "load_cycle_points": [{"t": e["video_t"], "person": e["person"], "action": e["action"], "dur_sec": e["dur_sec"]} for e in cycles],
    }
    Path(args.out).parent.mkdir(parents=True, exist_ok=True)
    Path(args.out).write_text(json.dumps(out, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(f"wrote {args.out} events={len(events)} load_cycles={len(cycles)} intervals={len(intervals)}")
    return 0


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