#!/usr/bin/env python3
"""What needs attention: the text version of the Attention view.

    tools/stale-report [--data DIR] [--today YYYY-MM-DD] [--expiry-window P60D] [ROOT ...]

Sections (charter §6, §12; rules in docs/data-format.md §4):
  OVERDUE        obligations whose due date has passed
  DUE SOON       obligations inside their lead time (default P30D)
  EXPIRING       documents / infrastructure with 'expires' inside the window
  STALE          records not verified within their review interval;
                 they must not be treated as current
  DO NOT TOUCH   things that must not be changed, cancelled, or deleted

Records whose start date is unknown are treated as possibly in effect and
included (templates default to valid_from: unknown).

Superseded and no-longer-valid records are history and are skipped.
Exit status 0 always (this is a report, not a check). Reads only.
"""
import argparse
import datetime as dt
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
import continuity_records as cr  # noqa: E402


def main() -> int:
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("roots", nargs="*", type=Path)
    ap.add_argument("--data", type=Path)
    ap.add_argument("--today", type=dt.date.fromisoformat, default=dt.date.today())
    ap.add_argument("--expiry-window", default="P60D")
    a = ap.parse_args()
    today = a.today

    roots = [(r.name, r) for r in a.roots] if a.roots else cr.vault_roots(a.data)
    if not roots:
        print("stale-report: no unlocked compartments found", file=sys.stderr)
        return 2
    records = [r for r in cr.load_vault(roots) if not r.parse_error]

    overdue, soon, expiring, stale, dnt = [], [], [], [], []
    horizon = cr.add_duration(today, a.expiry_window)
    for r in records:
        m = r.meta
        if cr.is_superseded(m):
            continue
        if cr.in_effect(m, today) is False:
            continue
        label = f"{m.get('title', r.path.stem)}  [{r.compartment} {r.id}]"
        if m.get("type") == "obligation":
            due = cr.to_date(m.get("due"))
            if due:
                start = cr.add_duration(due, str(m.get("lead_time") or cr.DEFAULT_LEAD_TIME), -1)
                days = (due - today).days
                if days < 0:
                    overdue.append((due, f"{due}  {-days} day(s) overdue  {label}\n      if missed: {m.get('consequence', 'unknown')}"))
                elif today >= start:
                    soon.append((due, f"{due}  in {days} day(s)  {label}"))
        exp = cr.to_date(m.get("expires"))
        if exp and exp <= horizon:
            expiring.append((exp, f"{exp}  {'EXPIRED' if exp < today else f'in {(exp - today).days} day(s)'}  {label}"))
        since = cr.stale_since(m, today)
        if since:
            verified = m.get("last_verified") or "never"
            stale.append((since, f"stale since {since} (last verified: {verified})  {label}"))
        if m.get("do_not_touch") is True:
            dnt.append(f"{label}\n      {m.get('do_not_touch_note', '')}")

    print(f"Continuity attention report, {today}  ({len(records)} records in {', '.join(c for c, _ in roots)})")
    for title, items, is_sorted in (
        ("OVERDUE", overdue, True), ("DUE SOON", soon, True), ("EXPIRING", expiring, True),
        ("STALE (do not treat as current)", stale, True), ("DO NOT TOUCH", dnt, False),
    ):
        print(f"\n{title}: {len(items)}")
        lines = [t for _, t in sorted(items, key=lambda x: x[0])] if is_sorted else items
        for line in lines:
            print(f"  - {line}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
