"""One-shot triage for the agent loop: everything that needs attention.

  .cad-venv/bin/python harness/triage.py         # human/agent-readable
  .cad-venv/bin/python harness/triage.py --json  # machine form

Sections: NEW telegram requests (need spec+build+status flip), OPEN studio
notes (need rebuild+resolve), FAILED/stale production jobs, and un-notified
finished requests (bot delivers those itself when running).
"""

from __future__ import annotations

import json
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path

STALL_MIN = 30

ROOT = Path(__file__).resolve().parent.parent
R = ROOT / "artifacts" / "review"


def _load(name: str, key: str) -> list | dict:
    f = R / name
    if not f.exists():
        return [] if key else {}
    data = json.loads(f.read_text())
    return data.get(key, []) if key else data


def _stalled(job: dict) -> bool:
    """A 'building' job older than STALL_MIN minutes has lost its thread
    (server restart/crash) — the customer is watching a spinner forever."""
    try:
        started = datetime.fromisoformat(job.get("started", ""))
    except ValueError:
        return True
    return datetime.now(timezone.utc) - started > timedelta(minutes=STALL_MIN)


def triage() -> dict:
    requests = _load("requests.json", "requests")
    comments = _load("comments.json", "comments")
    jobs = _load("jobs.json", "")
    return {
        "new_requests": [
            {"id": r["id"], "name": r["name"], "text": r["text"],
             "image": r.get("image"), "reply_to": r.get("reply_to")}
            for r in requests if r.get("status") == "new"],
        "open_notes": [
            {"id": c["id"], "design": c["design"], "text": c["text"]}
            for c in comments if c.get("status") == "open"],
        "failed_jobs": [
            {"name": n, **{k: v for k, v in j.items() if k != "result"},
             "errors": (j.get("result") or {}).get("errors")}
            for n, j in jobs.items() if j.get("status") == "failed"],
        "building": [n for n, j in jobs.items() if j.get("status") == "building"
                     and not _stalled(j)],
        "stalled_builds": [
            {"name": n, "started": j.get("started"),
             "fix": "restart serve.py, then POST /api/produce again"}
            for n, j in jobs.items()
            if j.get("status") == "building" and _stalled(j)],
        "awaiting_bot_delivery": [
            r["name"] for r in requests
            if r.get("status") in ("done", "failed") and not r.get("notified")],
    }


def main() -> int:
    t = triage()
    if "--json" in sys.argv:
        print(json.dumps(t, indent=1))
        return 0
    total = sum(len(v) for v in t.values())
    if not total:
        print("all clear — no requests, notes, or failed jobs")
        return 0
    for k, rows in t.items():
        if rows:
            print(f"{k} ({len(rows)}):")
            for r in rows:
                print(f"  - {r}")
    return 0


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