from __future__ import annotations

from app.modules.agent.engine.orchestrator.actions.project_qa_analyzer import ProjectQaAnalyzer
from app.modules.agent.engine.orchestrator.actions.common import ActionSupport
from app.modules.agent.engine.orchestrator.actions.project_qa_support import ProjectQaSupport
from app.modules.agent.engine.orchestrator.execution_context import ExecutionContext
from app.modules.agent.engine.orchestrator.models import ArtifactType


class ProjectQaActions(ActionSupport):
    def __init__(self) -> None:
        self._support = ProjectQaSupport()
        self._analyzer = ProjectQaAnalyzer()

    def classify_project_question(self, ctx: ExecutionContext) -> list[str]:
        message = str(ctx.task.user_message or "")
        profile = self._support.build_profile(message)
        return [self.put(ctx, "question_profile", ArtifactType.STRUCTURED_JSON, profile)]

    def collect_project_sources(self, ctx: ExecutionContext) -> list[str]:
        profile = self.get(ctx, "question_profile", {}) or {}
        terms = list(profile.get("terms", []) or [])
        entities = list(profile.get("entities", []) or [])
        rag_items = list(ctx.task.metadata.get("rag_items", []) or [])
        files_map = dict(ctx.task.metadata.get("files_map", {}) or {})
        explicit_test = any(term in {"test", "tests", "тест", "тесты"} for term in terms)

        ranked_rag = []
        for item in rag_items:
            score = self._support.rag_score(item, terms, entities)
            source = str(item.get("source", "") or "")
            if not explicit_test and self._support.is_test_path(source):
                score -= 3
            if score > 0:
                ranked_rag.append((score, item))
        ranked_rag.sort(key=lambda pair: pair[0], reverse=True)

        ranked_files = []
        for path, payload in files_map.items():
            score = self._support.file_score(path, payload, terms, entities)
            if not explicit_test and self._support.is_test_path(path):
                score -= 3
            if score > 0:
                ranked_files.append(
                    (
                        score,
                        {
                            "path": path,
                            "content": str(payload.get("content", "")),
                            "content_hash": str(payload.get("content_hash", "")),
                        },
                    )
                )
        ranked_files.sort(key=lambda pair: pair[0], reverse=True)

        bundle = {
            "profile": profile,
            "rag_items": [item for _, item in ranked_rag[:12]],
            "file_candidates": [item for _, item in ranked_files[:10]],
            "rag_total": len(ranked_rag),
            "files_total": len(ranked_files),
        }
        return [self.put(ctx, "source_bundle", ArtifactType.STRUCTURED_JSON, bundle)]

    def analyze_project_sources(self, ctx: ExecutionContext) -> list[str]:
        bundle = self.get(ctx, "source_bundle", {}) or {}
        profile = bundle.get("profile", {}) or {}
        rag_items = list(bundle.get("rag_items", []) or [])
        file_candidates = list(bundle.get("file_candidates", []) or [])

        if str(profile.get("domain")) == "code":
            analysis = self._analyzer.analyze_code(profile, rag_items, file_candidates)
        else:
            analysis = self._analyzer.analyze_docs(profile, rag_items)
        return [self.put(ctx, "analysis_brief", ArtifactType.STRUCTURED_JSON, analysis)]

    def build_project_answer_brief(self, ctx: ExecutionContext) -> list[str]:
        profile = self.get(ctx, "question_profile", {}) or {}
        analysis = self.get(ctx, "analysis_brief", {}) or {}
        brief = {
            "question_profile": profile,
            "resolved_subject": analysis.get("subject"),
            "key_findings": analysis.get("findings", []),
            "supporting_evidence": analysis.get("evidence", []),
            "missing_evidence": analysis.get("gaps", []),
            "answer_mode": analysis.get("answer_mode", "summary"),
        }
        return [self.put(ctx, "answer_brief", ArtifactType.STRUCTURED_JSON, brief)]

    def compose_project_answer(self, ctx: ExecutionContext) -> list[str]:
        brief = self.get(ctx, "answer_brief", {}) or {}
        profile = brief.get("question_profile", {}) or {}
        russian = bool(profile.get("russian"))
        answer_mode = str(brief.get("answer_mode") or "summary")
        findings = list(brief.get("key_findings", []) or [])
        evidence = list(brief.get("supporting_evidence", []) or [])
        gaps = list(brief.get("missing_evidence", []) or [])

        title = "## Кратко" if russian else "## Summary"
        lines = [title]
        if answer_mode == "inventory":
            lines.append("### Что реализовано" if russian else "### Implemented items")
        else:
            lines.append("### Что видно по проекту" if russian else "### What the project shows")
        if findings:
            lines.extend(f"- {item}" for item in findings)
        else:
            lines.append("Не удалось собрать подтвержденные выводы по доступным данным." if russian else "No supported findings could be assembled from the available data.")
        if evidence:
            lines.append("")
            lines.append("### Где смотреть в проекте" if russian else "### Where to look in the project")
            lines.extend(f"- `{item}`" for item in evidence[:5])
        if gaps:
            lines.append("")
            lines.append("### Что пока не подтверждено кодом" if russian else "### What is not yet confirmed in code")
            lines.extend(f"- {item}" for item in gaps[:3])
        return [self.put(ctx, "final_answer", ArtifactType.TEXT, "\n".join(lines))]
