"""Judge run: score ungraded traces with the calibrated judge.

Delegates to backend POST /judge-runs/{project}/run.
This module handles payload prep and terminal formatting.
"""

from __future__ import annotations

import re
from typing import Any


_INJECTION_PATTERNS = [
    re.compile(r"(?i)^\s*ignore\s+(previous|all|prior)\s+(instructions?|rules?)", re.IGNORECASE),
    re.compile(r"(?i)^\s*disregard\s+(previous|all|prior)", re.IGNORECASE),
    re.compile(r"(?i)^\s*forget\s+(everything|all|your)", re.IGNORECASE),
    re.compile(r"(?i)^\s*new\s+instructions?:", re.IGNORECASE),
]


def _sanitize_for_prompt(value: str) -> str:
    """Basic sanitization to reduce prompt injection risk."""
    if not value:
        return value
    sanitized = value
    for pattern in _INJECTION_PATTERNS:
        sanitized = pattern.sub(r"[FILTERED]", sanitized)
    return sanitized


def run_judge(
    traces: list[dict[str, Any]],
    client: Any,
    project: str,
    rejudge: bool = False,
) -> dict:
    """Score traces via the backend. Returns the raw response dict."""
    trace_payloads = [
        {
            "trace_id": trace.get("trace_id", "?"),
            "input": _sanitize_for_prompt(trace.get("input", "")),
            "output": _sanitize_for_prompt(trace.get("output", "")),
        }
        for trace in traces
    ]
    return client.run_judge(project, trace_payloads, rejudge=rejudge)


def format_run_summary(data: dict) -> str:
    """Format judge run results for terminal output."""
    total = data.get("total_scored", 0)
    passed = data.get("passed", 0)
    failed = data.get("failed", 0)
    parse_errors = data.get("parse_errors", 0)

    lines = [
        "",
        "  Judge Run Results",
        f"  {'─' * 50}",
        "",
        f"  Traces scored: {total}",
    ]
    if parse_errors:
        lines.append(f"  Parse errors (skipped): {parse_errors}")

    if total > 0:
        pass_rate = passed / total
        lines.extend([
            "",
            f"  Passed: {passed}  ({pass_rate:.0%})",
            f"  Failed: {failed}  ({1 - pass_rate:.0%})",
        ])

    fail_critiques = [
        tr.get("judge_critique", "")
        for tr in data.get("trace_results", [])
        if tr.get("judge_score") == 0
    ]
    if fail_critiques:
        lines.extend(["", "  Failure critiques:"])
        for critique in fail_critiques[:5]:
            preview = critique[:100] + ("..." if len(critique) > 100 else "")
            lines.append(f"    - {preview}")
        if len(fail_critiques) > 5:
            lines.append(f"    ... and {len(fail_critiques) - 5} more")

    lines.append("")
    return "\n".join(lines)
