"""Classify the TREATMENT of each internal citation edge (X11 Phase 2, #154).

Each row in ``precedent_internal_citations`` records that a committee decision
cited a precedent, with the surrounding ``match_context``. Until now the edge's
``treatment`` column was empty, so the verified/authority layer counted every
citation as if it were positive — a precedent *distinguished* N times got the
same authority boost as one *followed* N times (an INV-COR2 violation).

This script fills ``treatment`` per edge by classifying the context with
``corroboration.classify_treatment`` (Opus 4.8 @ xhigh via the local
claude_session bridge — LOCAL ONLY, the claude CLI is not in the container):

    followed | explained        → positive (counts toward authority)
    distinguished | criticized |
    questioned | overruled       → negative (never counts; overruled = demote)

Scope: only LINKED edges (``cited_case_law_id IS NOT NULL``) with an empty
``treatment`` and a non-empty ``match_context``. Idempotent — a second run skips
rows already classified. After applying, run ``scripts/build_verified_layer.py``
(or ``db.refresh_verified_layer``) so the treatment-aware count takes effect.

Run (dry-run, default — classifies and PRINTS, writes nothing):
    HOME=/home/chaim mcp-server/.venv/bin/python scripts/classify_citation_treatments.py
Apply:
    HOME=/home/chaim mcp-server/.venv/bin/python scripts/classify_citation_treatments.py --apply
Options:
    --limit N            classify at most N edges (smoke test)
    --case-law-id UUID   restrict to citations TO this one precedent
"""

from __future__ import annotations

import argparse
import asyncio
import os
import sys
from uuid import UUID

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "mcp-server", "src"))

from legal_mcp.services import corroboration, db  # noqa: E402


async def _pending(limit: int | None, case_law_id: str | None) -> list[dict]:
    pool = await db.get_pool()
    where = ["cited_case_law_id IS NOT NULL", "coalesce(treatment,'') = ''",
             "coalesce(match_context,'') <> ''"]
    params: list = []
    if case_law_id:
        params.append(UUID(case_law_id))
        where.append(f"cited_case_law_id = ${len(params)}")
    sql = (f"SELECT id, cited_case_number, match_context "
           f"FROM precedent_internal_citations WHERE {' AND '.join(where)} "
           f"ORDER BY created_at")
    if limit:
        sql += f" LIMIT {int(limit)}"
    rows = await pool.fetch(sql, *params)
    return [dict(r) for r in rows]


async def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--apply", action="store_true", help="write changes (default: dry-run)")
    ap.add_argument("--limit", type=int, default=None)
    ap.add_argument("--case-law-id", type=str, default=None)
    args = ap.parse_args()

    rows = await _pending(args.limit, args.case_law_id)
    print(f"קצוות לא-מסווגים לעיבוד: {len(rows)}\n")

    pool = await db.get_pool()
    counts: dict[str, int] = {}
    errors = 0
    for r in rows:
        try:
            t = await corroboration.classify_treatment(
                r["cited_case_number"] or "", r["match_context"] or "")
        except Exception as e:  # noqa: BLE001 — one bad row must not abort the batch
            errors += 1
            print(f"  ✗ [error] {r['cited_case_number']}: {type(e).__name__}: {e}")
            continue
        counts[t] = counts.get(t, 0) + 1
        sign = "＋" if corroboration.is_positive(t) else ("－" if corroboration.is_negative(t) else "·")
        print(f"  {sign} {t:<14} {r['cited_case_number']}")
        if args.apply:
            await pool.execute(
                "UPDATE precedent_internal_citations SET treatment = $2 WHERE id = $1",
                r["id"], t,
            )

    print(f"\nסיכום טיפול: {counts}  שגיאות={errors}"
          + ("" if args.apply else "   (dry-run — לא נכתב)"))
    if args.apply:
        print("הרץ עכשיו: scripts/build_verified_layer.py (או db.refresh_verified_layer) "
              "כדי שהספירה מודעת-הטיפול תיכנס לתוקף.")


if __name__ == "__main__":
    asyncio.run(main())
