"""סיכום-מנהלים של טענות הצדדים — מסמך פרוזה מזוקק להכנת היו"ר לדיון (WS3, #202).

מסמך זה הוא **נפרד ומובחן מטיוטת-הביניים** (החלטת-יו"ר, תוכנית workflow-redesign §WS3) —
תמצית מנהלים קצרה ומוקפדת של טענות הצדדים והתשובות זו-לזו, להכנה לדיון בעל-פה. אין הוא
משכפל את כתבי-הטענות המלאים: הוא מזקק.

מקור-האמת היחיד (G2): הוא נגזר מ-``legal_arguments`` (טיעונים מאוגדים) ומ-``claims``
הקיימים בתיק — לא מחלץ-מחדש ולא קורא לכתבי-הטענות הגולמיים. אם הטיעונים המאוגדים טרם
חושבו, הוא נופל-חזרה ל-claims הגולמיים (אותו מקור).

הייצור עובר ``claude_session.query`` → ``claude -p`` (CLI, מנוי claude.ai, עלות-שולית-אפס),
נעוץ ל-Opus 4.8 + effort=high — משימת זיקוק/סינתזה. **local-only**: לקונטיינר אין claude CLI;
לכן הכלי רץ רק מ-MCP-server המקומי, וה-endpoint ב-app.py רק מגיש את הקובץ השמור (לא מייצר).

ההזהרה נגד-הזיה (INV-AH): המסמך מתוחם לחלוטין לטענות-התיק עצמן. אסור להמציא טענה, הלכה
או עובדה שאינה מופיעה בקלט; טענה שאינה ברורה — מצוין במפורש, לא משלים.
"""

from __future__ import annotations

import logging
from datetime import date
from pathlib import Path
from uuid import UUID

from legal_mcp import config
from legal_mcp.services import (
    argument_aggregator,
    block_writer,
    claude_session,
    db,
    git_sync,
    storage,
)

logger = logging.getLogger(__name__)

# Saved alongside the legal analysis (same research folder, same git+S3 mirror path).
_SUMMARY_FILENAME = "party-claims-summary.md"

_PARTY_HE = {
    "appellant": "העוררים",
    "respondent": "המשיבים",
    "committee": "הוועדה המקומית",
    "permit_applicant": "מבקשי ההיתר",
    "unknown": "צד לא מזוהה",
}


def summary_file_path(case_number: str) -> Path:
    """Resolve the saved party-claims-summary.md path for a case."""
    return config.find_case_dir(case_number) / "documents" / "research" / _SUMMARY_FILENAME


async def _build_arguments_context(case_id: UUID) -> tuple[str, int, str]:
    """Build the grounded source block from the case's OWN claims/arguments.

    Preference order (single source of truth, no re-extraction — G2):
      1. ``legal_arguments`` — the aggregated, de-duplicated arguments per party.
      2. fallback to raw ``claims`` when arguments were never aggregated.

    Returns ``(context_text, item_count, source_kind)`` where ``source_kind`` is
    ``"arguments"`` or ``"claims"`` (or ``"none"`` when neither exists).
    """
    args = await argument_aggregator.get_legal_arguments(case_id)
    if args:
        by_party: dict[str, list[dict]] = {}
        for a in args:
            by_party.setdefault(a["party"], []).append(a)

        lines: list[str] = []
        for party, items in by_party.items():
            lines.append(f"\n## {_PARTY_HE.get(party, party)}")
            for a in items:
                title = (a.get("argument_title") or "").strip()
                body = (a.get("argument_body") or "").strip()
                topic = (a.get("legal_topic") or "").strip()
                header = f"- **{title}**" if title else "-"
                if topic:
                    header += f" [{topic}]"
                lines.append(header)
                if body:
                    lines.append(f"  {body}")
        return "\n".join(lines), len(args), "arguments"

    # Fallback — raw claims, the same underlying source.
    claims = await db.get_claims(case_id)
    # Exclude block-zayin (decision-summary) claims — original pleadings only.
    source_claims = [c for c in claims if c.get("source_document", "") != "block-zayin"] or claims
    if not source_claims:
        return "", 0, "none"

    lines = []
    current_role = ""
    role_he = {"appellant": "טענות העוררים", "respondent": "טענות המשיבים",
               "committee": "עמדת הוועדה המקומית", "permit_applicant": "עמדת מבקשי ההיתר"}
    n = 0
    for c in source_claims:
        if c["party_role"] != current_role:
            current_role = c["party_role"]
            lines.append(f"\n## {role_he.get(current_role, current_role)}")
        n += 1
        lines.append(f"- טענה #{n}: {c['claim_text']}")
    return "\n".join(lines), len(source_claims), "claims"


_PROMPT_TEMPLATE = """אתה מכין עבור יו"ר ועדת הערר (עו"ד דפנה תמיר) **סיכום-מנהלים מזוקק של טענות הצדדים** — מסמך פרוזה קצר שמטרתו אחת: להכין את היו"ר לדיון בעל-פה. זהו מסמך **נפרד** מטיוטת-ההחלטה ואינו חלק ממנה.

## פרטי התיק:
{case_context}

## הקלט — טענות/טיעוני הצדדים (מקור-האמת היחיד):
{arguments_context}

## כללי-כתיבה מחייבים:
- **זיקוק, לא שכפול.** אל תעתיק את כתבי-הטענות. תמצת כל צד ל-2–5 משפטי-מפתח. היעד: עמוד אחד עד שניים, לא יותר.
- **מבוסס-קלט בלבד (חובה אנטי-הזיה).** הסתמך אך-ורק על הטענות שבקלט לעיל. אסור להמציא טענה, הלכה, פסק-דין, מספר או עובדה שאינם בקלט. טענה שאינה ברורה או חסרה — ציין זאת במפורש ("הטענה לא פורטה"), אל תשלים מדמיונך.
- **ניטרלי.** הצג את עמדת כל צד בנאמנות, בלי להעריך, בלי להכריע ובלי לרמוז על תוצאה. אין זו החלטה — זו הכנה.
- **מבנה קבוע:**
  1. פסקת-פתיחה קצרה (משפט–שניים): במה עוסק הערר ומיהם הצדדים.
  2. **טענות העוררים** — תמצית מזוקקת.
  3. **טענות המשיבים / הוועדה / מבקשי ההיתר** — תמצית מזוקקת (כל צד שקיים בקלט).
  4. **נקודות-המחלוקת המרכזיות** — 2–4 הסוגיות שעליהן ניצבת ההכרעה, כשאלות פתוחות (לא תשובות).
- **סגנון:** עברית משפטית בהירה, גוף-שלישי לתיאור הצדדים. בלי כותרת "החלטה". בלי חתימות.

## מדריך-סגנון (לטון בלבד — אל תיישם מבנה-החלטה):
{style_context}

החזר אך-ורק את גוף מסמך הסיכום (Markdown), בלי הקדמות ובלי הסברים על מה שעשית."""


async def summarize_party_claims(case_id: UUID, case_number: str,
                                 instructions: str = "") -> dict:
    """Generate the distilled executive summary of party claims and save it.

    Grounded strictly in the case's own claims/legal_arguments (INV-AH).
    Generation is pinned to Opus 4.8 + effort=high (distillation/synthesis).
    """
    case = await db.get_case(case_id)
    if not case:
        raise ValueError(f"Case {case_id} not found")

    decision = await db.get_decision_by_case(case_id)

    arguments_context, n_items, source_kind = await _build_arguments_context(case_id)
    if source_kind == "none":
        raise ValueError(
            "אין טענות לסכם. הרץ extract_claims (ורצוי aggregate_claims_to_arguments) קודם."
        )

    case_context = block_writer._build_case_context(case, decision)
    style_context = await block_writer._build_style_context(case.get("practice_area", ""))

    prompt = _PROMPT_TEMPLATE.format(
        case_context=case_context,
        arguments_context=arguments_context,
        style_context=style_context,
    )
    if instructions:
        prompt += f"\n\n## הנחיות נוספות מהיו\"ר:\n{instructions}"

    # Generation: claude_session → claude -p, pinned Opus 4.8 + high effort.
    # tools="" — pure prose, no tool_use (avoids error_max_turns). LONG_TIMEOUT:
    # full-case context can be large.
    content = await claude_session.query(
        prompt,
        timeout=claude_session.LONG_TIMEOUT,
        model="claude-opus-4-8",
        effort="high",
        tools="",
    )
    content = (content or "").strip()
    if not content:
        raise ValueError("הסיכום חזר ריק מ-claude -p.")

    today = date.today().strftime("%d.%m.%Y")
    header = (
        f"# סיכום-מנהלים — טענות הצדדים\n\n"
        f"**תיק:** {case['case_number']}  \n"
        f"**נושא:** {case.get('subject', '')}  \n"
        f"**הופק:** {today} · מסמך הכנה לדיון (נפרד מטיוטת-ההחלטה)\n\n"
        f"---\n\n"
    )
    document = header + content + "\n"

    # Save to data/cases/{n}/documents/research/ — same path as the legal analysis,
    # so it is git-synced + S3-mirrored by the existing machinery.
    out_path = summary_file_path(case_number)
    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(document, encoding="utf-8")  # noqa: STG1 — mirrored below
    try:
        key = out_path.resolve().relative_to(Path(config.DATA_DIR).resolve()).as_posix()
        await storage.mirror(key, document.encode("utf-8"), bucket=storage.Bucket.DOCUMENTS)
    except ValueError:
        pass

    case_dir = config.find_case_dir(case_number)
    if case_dir.exists():
        git_sync.commit_and_push(case_dir, f"סיכום-מנהלים: טענות הצדדים ({case_number})")

    return {
        "case_number": case_number,
        "path": str(out_path),
        "source_kind": source_kind,
        "source_items": n_items,
        "word_count": len(content.split()),
        "message": f"סיכום-מנהלים נוצר ({len(content.split())} מילים, מקור: {source_kind}).",
    }
