"""Сервис починки черновика ответа по результатам post-evidence gate (LLM repair)."""

from __future__ import annotations

import json

from app.modules.agent.runtime.steps.gates.post.post_gate import RuntimeValidationResult
from app.modules.agent.llm import AgentLlmService


class RuntimeAnswerRepairService:
    def __init__(self, llm: AgentLlmService) -> None:
        self._llm = llm

    def repair(
        self,
        *,
        draft_answer: str,
        validation: RuntimeValidationResult,
        prompt_payload: str,
    ) -> str:
        repair_focus = self._repair_focus(validation.reasons)
        repair_input = json.dumps(
            {
                "draft_answer": draft_answer,
                "validation_reasons": validation.reasons,
                "repair_focus": repair_focus,
                "prompt_payload": prompt_payload,
            },
            ensure_ascii=False,
            indent=2,
        )
        return self._llm.generate(
            "code_qa_repair_answer",
            repair_input,
            log_context="graph.project_qa.code_qa.repair",
        ).strip()

    def _repair_focus(self, reasons: list[str]) -> list[str]:
        mapping = {
            "missing_concrete_methods": "missing_concrete_methods",
            "missing_concrete_calls": "missing_concrete_calls",
            "missing_concrete_dependencies": "missing_concrete_dependencies",
            "missing_concrete_fields": "missing_concrete_fields",
            "ignores_concrete_explain_facts": "too_vague_for_explain",
            "too_vague_for_explain": "too_vague_for_explain",
            "missing_concrete_components": "missing_concrete_components",
            "missing_concrete_relations": "missing_concrete_relations",
            "missing_relation_verbs": "missing_relation_verbs",
            "target_mentioned_but_no_relations": "missing_concrete_relations",
            "too_vague_for_architecture": "too_vague_for_architecture",
            "missing_flow_steps": "missing_flow_steps",
            "missing_sequence_edges": "missing_sequence_edges",
            "missing_ordered_flow_steps": "missing_flow_steps",
            "too_vague_for_trace_flow": "too_vague_for_trace_flow",
            "semantic_labels_without_code_edges": "semantic_labels_without_code_edges",
            "contains_retrieval_artifacts": "contains_retrieval_artifacts",
            "methods_as_primary_components": "methods_as_primary_components",
            "overclaims_trace_completeness": "overclaims_trace_completeness",
        }
        seen: set[str] = set()
        result: list[str] = []
        for reason in reasons:
            focus = mapping.get(reason)
            if focus and focus not in seen:
                seen.add(focus)
                result.append(focus)
        return result or ["tighten_to_evidence"]
