from __future__ import annotations

import json
from dataclasses import asdict

from app.core.agent.processes.v2 import V2IntentRouter
from tests.pipeline_setup_v4.core.models import ExecutionPayload, V4Case


class _KeywordLlm:
    _FILE_MARKERS = (
        "в каком файле",
        "в каком документе",
        "в каких файлах",
        "какие файлы относятся",
        "покажи файл",
        "покажи документ",
        "где описано",
        "где описан",
        "где описана",
        "где описаны",
        "где находится",
        "найди файл",
        "найди файлы",
        "show doc",
        "show file",
        "doc for",
        "file with",
    )
    _DOC_MARKERS = (
        "документац",
        "endpoint",
        "эндпоинт",
        "архитект",
        "architecture",
        "overview архитектуры",
        "arch overview",
        "процесс",
        "process",
        "flow",
        "workflow",
        "сущност",
        "worker",
        "цикл отправки уведомлений",
        "ручная отправка сообщения",
        "runtime health",
        "здоров",
        "runtime",
        "health",
        "telegram",
        "api",
        "docs/",
        "/health",
        "/send",
        "/actions/{action}",
        "billing invoice process",
        "billing invoice flow",
        "billing invoice docs",
        "notify app",
    )
    _GENERAL_MARKERS = (
        "что это за сервис",
        "для чего нужен",
        "какую задачу решает",
        "общий обзор",
        "что входит в документацию",
        "какие документы стоит читать сначала",
        "дай короткое summary",
        "что тут есть кроме api",
        "как в целом устроено приложение",
        "какие основные части есть",
        "как сервис взаимодействует с telegram в целом",
        "что это",
        "для чего",
    )

    def generate(self, _prompt_name: str, user_input: str, **_kwargs) -> str:
        payload = json.loads(user_input)
        query = str(payload.get("normalized_query") or "").lower()
        route = self._select(query)
        return json.dumps(route, ensure_ascii=False)

    def _select(self, query: str) -> dict[str, object]:
        if any(marker in query for marker in self._FILE_MARKERS) or ("дока" in query and "покажи" in query) or ".md" in query:
            return self._route("DOCS", "DOC_EXPLAIN", "FIND_FILES", "file lookup")
        if any(marker in query for marker in self._GENERAL_MARKERS):
            return self._route("GENERAL", "GENERAL_QA", "SUMMARY", "general overview")
        if any(marker in query for marker in self._DOC_MARKERS):
            return self._route("DOCS", "DOC_EXPLAIN", "SUMMARY", "docs topic")
        return self._route("GENERAL", "GENERAL_QA", "SUMMARY", "default general")

    def _route(self, domain: str, intent: str, subintent: str, reason: str) -> dict[str, object]:
        return {
            "routing_domain": domain,
            "intent": intent,
            "subintent": subintent,
            "confidence": 0.93,
            "reason_short": reason,
        }


class ProcessV2IntentRouterExecutor:
    def __init__(self) -> None:
        self._router = V2IntentRouter(llm=_KeywordLlm(), enable_llm_disambiguation=True)

    def execute(self, case: V4Case) -> ExecutionPayload:
        route = self._router.route(case.query)
        route_dump = asdict(route)
        actual = {
            "domain": route.routing_domain,
            "intent": route.intent,
            "sub_intent": route.subintent,
            "routing_mode": route.routing_mode,
            "llm_router_used": route.llm_router_used,
            "confidence": route.confidence,
        }
        details = {
            "query": case.query,
            "route": route_dump,
            "pipeline_steps": [
                {
                    "step": "intent_router",
                    "input": {"query": case.query},
                    "output": {
                        "domain": route.routing_domain,
                        "intent": route.intent,
                        "sub_intent": route.subintent,
                        "reason_short": route.reason_short,
                        "target_terms": list(route.target_terms),
                        "anchors": route_dump.get("anchors") or {},
                    },
                }
            ],
        }
        return ExecutionPayload(actual=actual, details=details)
