from __future__ import annotations

from dataclasses import dataclass, field

from app.modules.rag.explain.models import ExplainPack


@dataclass(slots=True)
class EvidenceGateDecision:
    passed: bool
    answer: str = ""
    diagnostics: dict[str, list[str]] = field(default_factory=dict)


class CodeExplainEvidenceGate:
    def __init__(self, min_excerpts: int = 2) -> None:
        self._min_excerpts = min_excerpts

    def evaluate(self, pack: ExplainPack) -> EvidenceGateDecision:
        diagnostics = self._diagnostics(pack)
        if len(pack.code_excerpts) >= self._min_excerpts:
            return EvidenceGateDecision(passed=True, diagnostics=diagnostics)
        return EvidenceGateDecision(
            passed=False,
            answer=self._build_answer(pack, diagnostics),
            diagnostics=diagnostics,
        )

    def _diagnostics(self, pack: ExplainPack) -> dict[str, list[str]]:
        return {
            "entrypoints": [item.title for item in pack.selected_entrypoints[:3] if item.title],
            "symbols": [item.title for item in pack.seed_symbols[:5] if item.title],
            "paths": self._paths(pack),
            "missing": list(pack.missing),
        }

    def _paths(self, pack: ExplainPack) -> list[str]:
        values: list[str] = []
        for item in pack.selected_entrypoints + pack.seed_symbols:
            path = item.source or (item.location.path if item.location else "")
            if path and path not in values:
                values.append(path)
        for excerpt in pack.code_excerpts:
            if excerpt.path and excerpt.path not in values:
                values.append(excerpt.path)
        return values[:6]

    def _build_answer(self, pack: ExplainPack, diagnostics: dict[str, list[str]]) -> str:
        lines = [
            "Недостаточно опоры в коде, чтобы дать объяснение без догадок.",
            "",
            f"Найдено фрагментов кода: {len(pack.code_excerpts)} из {self._min_excerpts} минимально необходимых.",
        ]
        if diagnostics["paths"]:
            lines.append(f"Пути: {', '.join(diagnostics['paths'])}")
        if diagnostics["entrypoints"]:
            lines.append(f"Entrypoints: {', '.join(diagnostics['entrypoints'])}")
        if diagnostics["symbols"]:
            lines.append(f"Символы: {', '.join(diagnostics['symbols'])}")
        if diagnostics["missing"]:
            lines.append(f"Диагностика: {', '.join(diagnostics['missing'])}")
        return "\n".join(lines).strip()
