"""MCP tools for attached legal precedents (user-supplied case-law quotes).

These complement the existing `case_law` table (which is populated from
structured sources and is what the block-writer RAG searches) by storing
free-text citations the chair attaches during the compose phase.
"""

from __future__ import annotations

from uuid import UUID

from legal_mcp.services import db
from legal_mcp.tools.envelope import empty, err, ok  # GAP-48: SSoT envelope


async def precedent_attach(
    case_number: str,
    quote: str,
    citation: str,
    section_id: str = "",
    chair_note: str = "",
    pdf_document_id: str = "",
) -> str:
    """צירוף פסיקה תומכת לתיק ערר.

    Args:
        case_number: מספר תיק הערר
        quote: הציטוט המדויק שיוכנס להחלטה
        citation: מראה המקום (ערר 1126-08-25 ... נ' ... (נבו 9.3.2026))
        section_id: מזהה הטענה/סוגיה (threshold_1, issue_3); ריק = כללי לתיק
        chair_note: הערה אופציונלית — למה הציטוט תומך בעמדה
        pdf_document_id: מזהה קובץ PDF מצורף (אופציונלי)
    """
    case = await db.get_case_by_number(case_number)
    if not case:
        return err(f"תיק {case_number} לא נמצא.")

    pdf_uuid: UUID | None = None
    if pdf_document_id:
        try:
            pdf_uuid = UUID(pdf_document_id)
        except ValueError:
            return err("pdf_document_id לא תקין")

    # INV-TOOL3 / GAP-52: idempotent on (case_id, section_id, citation, quote).
    # Re-attaching the same quote to the same section returns the existing row.
    for _p in await db.list_case_precedents(UUID(case["id"])):
        if (_p.get("citation") == citation and _p.get("quote") == quote
                and (_p.get("section_id") or None) == (section_id or None)):
            _p["idempotent_existing"] = True
            return ok(_p)

    row = await db.create_case_precedent(
        case_id=UUID(case["id"]),
        quote=quote,
        citation=citation,
        section_id=section_id or None,
        chair_note=chair_note,
        pdf_document_id=pdf_uuid,
        practice_area=case.get("practice_area"),
    )
    return ok(row)


async def precedent_list(case_number: str) -> str:
    """רשימת כל הפסיקות שצורפו לתיק, ממוינות לפי סעיף ואז לפי זמן יצירה."""
    case = await db.get_case_by_number(case_number)
    if not case:
        return err(f"תיק {case_number} לא נמצא.")

    rows = await db.list_case_precedents(UUID(case["id"]))
    return ok(rows)


async def precedent_remove(precedent_id: str) -> str:
    """הסרת פסיקה מצורפת. קובץ ה-PDF (אם צורף) נשאר ב-documents לצורך audit."""
    try:
        pid = UUID(precedent_id)
    except ValueError:
        return err("precedent_id לא תקין")

    deleted = await db.delete_case_precedent(pid)
    return ok({"deleted": deleted, "precedent_id": precedent_id})


async def search_case_precedents(
    query: str, practice_area: str = "", limit: int = 10,
) -> str:
    """חיפוש רוחבי בציטוטי-הפסיקה שצורפו ידנית לתיקים (case_precedents) — קורפוס
    "case-attached". GAP-49 (INV-TOOL2): שם קודם `precedent_search_library` (מטעה).
    זו **אינה** ספריית-הפסיקה הסמכותית — לזו השתמש ב-`search_precedent_library`.

    Args:
        query: מחרוזת חיפוש (מתחרה מול citation ומול quote)
        practice_area: אופציונלי — סינון לתחום משפטי מסוים
        limit: מספר תוצאות מקסימלי
    """
    if not query or len(query.strip()) < 2:
        return empty("שאילתה קצרה מדי (פחות מ-2 תווים).")

    rows = await db.search_precedent_library(query.strip(), practice_area, limit)
    return ok(rows)
