"""MCP tools for the internal-decisions citation graph (TaskMaster #34).

The citation graph captures pointers between Daphna's (and other internal
committee chairs') decisions: when one ruling cites another, ``precedent_
internal_citations`` records the edge — resolved against ``case_law`` when
the cited row exists, kept as a stub when it doesn't.

Three tools:

- ``extract_internal_citations`` — run regex extraction on one row (by id) or
  on every internal-committee row filtered by chair (e.g. Daphna only).
  Idempotent: re-running does not duplicate rows (ON CONFLICT DO NOTHING).
- ``list_internal_citations`` — outgoing edges from a source row. Optional
  ``linked_only`` filter for rows resolved to existing case_law UUIDs.
- ``list_incoming_citations`` — incoming edges to a target row ("which
  Daphna decisions cite this ruling?").

These tools are *manual triggers*. The pipeline runs them after a new
internal-decision upload, but the chair / researcher can also re-run on
demand (for example after fixing OCR or after uploading a previously-
missing decision so that newer rows now link to it).
"""

from __future__ import annotations

from uuid import UUID

from legal_mcp.services import citation_extractor
from legal_mcp.tools.envelope import err as _err, ok as _ok  # GAP-48: SSoT envelope


async def extract_internal_citations(
    case_law_id: str = "",
    chair_name: str = "",
    limit: int = 0,
) -> str:
    """חילוץ ציטוטים פנימיים מהחלטות ועדת ערר ושמירה ב-precedent_internal_citations.

    Args:
        case_law_id: UUID של החלטה ספציפית. אם ריק וגם chair_name ריק — מריץ
            על כל ההחלטות internal_committee. אם מסופק, חייב לעבור על שורה אחת
            בלבד (משתמש בזה אחרי upload).
        chair_name: שם יו"ר (כגון 'דפנה תמיר'). מסנן את האצווה. ריק = כל היו"רים.
        limit: עליון על מספר רשומות שיעובדו (0 = ללא הגבלה). שימושי לבדיקה.

    הכלי איידמפוטנטי — ON CONFLICT DO NOTHING על (source_case_law_id, cited_case_number).
    מחזיר סטטיסטיקה: extracted, linked, new, skipped, failed.
    """
    if case_law_id.strip() and chair_name.strip():
        return _err("יש לספק case_law_id או chair_name, לא שניהם")

    if case_law_id.strip():
        try:
            cl_uuid = UUID(case_law_id.strip())
        except ValueError:
            return _err("case_law_id לא תקין")
        try:
            stats = await citation_extractor.extract_and_store(cl_uuid)
        except Exception as e:
            return _err(str(e))
        return _ok(stats)

    try:
        stats = await citation_extractor.extract_all_internal_committee(
            chair_name_filter=chair_name.strip(),
            limit=int(limit) if limit else 0,
        )
    except Exception as e:
        return _err(str(e))
    return _ok(stats)


async def list_internal_citations(
    case_law_id: str = "",
    linked_only: bool = False,
    limit: int = 50,
) -> str:
    """רשימת ציטוטים יוצאים מהחלטה (מה ההחלטה הזו מצטטת).

    Args:
        case_law_id: UUID של ה-case_law (חובה).
        linked_only: True = רק ציטוטים שקושרו ל-case_law קיים בקורפוס.
        limit: עליון על מספר תוצאות (default 50).

    Returns: JSON עם list של ציטוטים, כולל target_case_number/name/chair
        כשהם linked. אם linked_only=False, ציטוטים בלתי קושרים יחזרו עם
        cited_case_law_id=null וניתן להעלות אותם דרך internal_decision_upload.
    """
    if not case_law_id.strip():
        return _err("case_law_id חובה")
    try:
        cl_uuid = UUID(case_law_id.strip())
    except ValueError:
        return _err("case_law_id לא תקין")
    try:
        rows = await citation_extractor.list_citations_for_case_law(
            cl_uuid, linked_only=bool(linked_only),
        )
    except Exception as e:
        return _err(str(e))
    return _ok({"items": rows[: max(1, int(limit))], "count": len(rows)})


async def list_incoming_citations(
    case_law_id: str = "",
    limit: int = 50,
) -> str:
    """רשימת ציטוטים נכנסים אל החלטה (אילו החלטות מצטטות אותה).

    שימוש: רוצים לדעת אילו החלטות של דפנה הסתמכו על פסק דין מסוים?
    מעבירים את ה-case_law_id של פסק הדין הזה.

    Args:
        case_law_id: UUID של ה-target case_law (חובה).
        limit: עליון על מספר תוצאות.
    """
    if not case_law_id.strip():
        return _err("case_law_id חובה")
    try:
        cl_uuid = UUID(case_law_id.strip())
    except ValueError:
        return _err("case_law_id לא תקין")
    try:
        rows = await citation_extractor.list_citations_to_case_law(cl_uuid)
    except Exception as e:
        return _err(str(e))
    return _ok({"items": rows[: max(1, int(limit))], "count": len(rows)})
