"""LLM-powered failure analysis for report suggestions."""

from __future__ import annotations

import logging

from evalkit.judges.base import BaseJudge
from evalkit.models import EvaluationResult
from evalkit.prompts.report_analysis import METRIC_DESCRIPTIONS, TEMPLATE

logger = logging.getLogger(__name__)

MAX_FAILURES = 10


def parse_analysis(reason: str) -> str:
    analysis = ""
    priority = ""
    if "ANALYSIS:" in reason:
        parts = reason.split("ANALYSIS:", 1)[1]
        if "PRIORITY FIX:" in parts:
            analysis, priority = parts.split("PRIORITY FIX:", 1)
            analysis = analysis.strip()
            priority = priority.strip()
        else:
            analysis = parts.strip()
    else:
        analysis = reason.strip()

    if priority:
        return f"{analysis}\nPriority fix: {priority}"
    return analysis


def _format_failure(idx: int, score: float, result: EvaluationResult) -> str:
    tc = result.test_case
    context_summary = "; ".join(c[:100] for c in tc.context[:3])
    if len(tc.context) > 3:
        context_summary += f" ... (+{len(tc.context) - 3} more chunks)"
    lines = [
        f"--- Failure {idx} (score: {score:.2f}) ---",
        f"Question: {tc.question[:200]}",
        f"Context: {context_summary or '(empty)'}",
        f"Answer: {tc.answer[:200]}",
    ]
    if tc.expected_answer:
        lines.append(f"Expected: {tc.expected_answer[:200]}")
    return "\n".join(lines)


def analyze_failure_group(
    metric_name: str,
    failures: list[tuple[float, EvaluationResult]],
    judge: BaseJudge | None,
) -> str | None:
    if judge is None or not failures:
        return None

    capped = failures[:MAX_FAILURES]
    failure_details = "\n\n".join(_format_failure(i + 1, score, result) for i, (score, result) in enumerate(capped))
    description = METRIC_DESCRIPTIONS.get(metric_name, metric_name)
    prompt = TEMPLATE.format(
        metric_name=metric_name,
        metric_description=description,
        failure_details=failure_details,
    )

    try:
        response = judge.evaluate(prompt)
        return parse_analysis(response.reason)
    except Exception:
        logger.exception("LLM analysis failed for metric %s", metric_name)
        return None
