#!/usr/bin/env python3
"""GAP-51 — נרמול ערכי outcome לאוצר-המילים הקנוני (FU-14).

ממפה את אוצר-המילים הישן של `set_outcome` לקנוני בשתי עמודות:
  decisions.outcome  ו-  cases.expected_outcome
    rejected  → rejection
    accepted  → full_acceptance
    partial   → partial_acceptance

דטרמיניסטי וקטן (~9 שורות). `betterment_levy` אינו קיים בנתונים ואינו ממופה
(הוא practice_area, לא outcome). הקוד כבר canonicalize בקריאה, אז המיגרציה היא
לניקיון בלבד — לא חוסמת.

שימוש:
    python3 scripts/migrate_gap51_outcomes.py            # dry-run (ברירת מחדל)
    python3 scripts/migrate_gap51_outcomes.py --apply    # גיבוי ואז עדכון

דורש POSTGRES_URL / DATABASE_URL בסביבה. נוגע רק ב-cases/decisions — לא בטבלאות
החילוץ (case_law/halachot), כך שבטוח להריץ במקביל לחילוץ פעיל.
"""
from __future__ import annotations

import argparse
import asyncio
import csv
import os
from datetime import datetime, timezone
from pathlib import Path

import asyncpg

MAP = {"rejected": "rejection", "accepted": "full_acceptance", "partial": "partial_acceptance"}
TARGETS = [("decisions", "outcome"), ("cases", "expected_outcome")]
AUDIT_DIR = Path(__file__).resolve().parent.parent / "data" / "audit"


def _db_url() -> str:
    url = os.environ.get("POSTGRES_URL") or os.environ.get("DATABASE_URL", "")
    if not url:
        raise SystemExit("POSTGRES_URL / DATABASE_URL not set")
    return url


async def main(apply: bool) -> None:
    conn = await asyncpg.connect(_db_url())
    try:
        affected = []
        for table, col in TARGETS:
            rows = await conn.fetch(
                f"SELECT id, {col} AS val FROM {table} WHERE {col} = ANY($1::text[])",
                list(MAP.keys()),
            )
            for r in rows:
                affected.append((table, col, str(r["id"]), r["val"], MAP[r["val"]]))

        print(f"GAP-51 outcome migration — {len(affected)} שורות מושפעות:")
        for t, c, rid, old, new in affected:
            print(f"  {t}.{c}  {rid}  {old} → {new}")
        if not affected:
            print("אין מה לנרמל — כל הערכים כבר קנוניים.")
            return
        if not apply:
            print("\n(dry-run — להחלה הוסף --apply)")
            return

        ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
        AUDIT_DIR.mkdir(parents=True, exist_ok=True)
        backup = AUDIT_DIR / f"gap51-outcome-backup-{ts}.csv"
        with backup.open("w", newline="", encoding="utf-8") as f:
            w = csv.writer(f)
            w.writerow(["table", "column", "id", "old_value", "new_value"])
            w.writerows(affected)
        print(f"\nגיבוי נכתב: {backup}")

        async with conn.transaction():
            for table, col in TARGETS:
                for old, new in MAP.items():
                    await conn.execute(
                        f"UPDATE {table} SET {col} = $1 WHERE {col} = $2", new, old,
                    )
        print(f"הוחלו {len(affected)} עדכונים בהצלחה.")
    finally:
        await conn.close()


if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("--apply", action="store_true", help="execute (default: dry-run)")
    asyncio.run(main(ap.parse_args().apply))
