from __future__ import annotations

import re


class DocsSubIntentDetector:
    _ENTITY_LIKE_TOKEN_RE = re.compile(r"\b[A-Z][A-Za-z0-9]+(?:Health|Status|State)\b")
    _CAMEL_ENTITY_CONTEXT_RE = re.compile(r"\b[A-Z][a-z0-9]+(?:[A-Z][A-Za-z0-9]+)+\b")
    _RELATED_MARKERS = (
        "найди документацию",
        "документация по",
        "где в документации",
        "что связано",
        "связанные документы",
        "что дальше читать",
        "по каким документам идти",
        "родительский документ",
        "дочерние документы",
        "какие документы",
        "что еще посмотреть",
        "где еще описано",
        "где еще используется",
        "с чем связан",
        "какие страницы связаны",
    )
    _FLOW_MARKERS = (
        "цикл",
        "как работает",
        "lifecycle",
        "как происходит",
        "как устроен",
        "как устроена",
        "как проходит",
        "последовательность",
        "шаги",
        "флоу",
        "flow",
        "workflow",
        "сценар",
        "процесс",
        "по шагам",
    )
    _API_MARKERS = (
        "api",
        "endpoint",
        "method",
        "route",
        "handler",
        "контракт",
        "request",
        "response",
        "webhook",
        "метод",
        "эндпоинт",
        "роут",
    )
    _ENTITY_MARKERS = (
        "сущност",
        "entity",
        "модел",
        "бизнес-объект",
        "что такое",
        "что за",
        "объект",
        "как используется",
    )
    _COMPONENT_MARKERS = (
        "компонент",
        "модул",
        "сервис",
        "класс",
        "блок",
        "подсистем",
        "часть системы",
        "роль",
        "какую роль",
        "manager",
        "worker",
        "channel",
        "service",
        "module",
    )
    _GENERAL_MARKERS = (
        "что вообще",
        "в целом",
        "с чего начать",
        "обзор",
        "какая структура документации",
        "какая документация есть",
        "что описано",
        "что есть в документации",
        "обзор документации",
    )
    _NATURAL_ENTITY_MARKERS = ("runtime health", "health state", "статус воркера", "состояние воркера", "состояние runtime")
    _NATURAL_FLOW_MARKERS = ("health check runtime", "проверка состояния", "как работает health check", "как происходит проверка")

    def detect(self, raw: str, *, intent: str = "DOCUMENTATION_EXPLAIN") -> str:
        candidates = self.rank_candidates(raw, intent=intent)
        return candidates[0][0] if candidates else "COMPONENT_EXPLAIN"

    def rank_candidates(self, raw: str, *, intent: str = "DOCUMENTATION_EXPLAIN") -> list[tuple[str, int]]:
        source = raw or ""
        text = " ".join(source.lower().split())
        if intent == "GENERAL_QA":
            return [("GENERIC_QA", 100)]
        if intent == "OPENAPI_GENERATION":
            return [(self._detect_openapi(text), 100)]
        if not text:
            return [("COMPONENT_EXPLAIN", 1)]
        scores = {
            "RELATED_DOCS_EXPLAIN": 0,
            "API_METHOD_EXPLAIN": 0,
            "ENTITY_EXPLAIN": 0,
            "COMPONENT_EXPLAIN": 0,
            "SYSTEM_FLOW_EXPLAIN": 0,
            "GENERIC_QA": 0,
        }
        if any(marker in text for marker in self._RELATED_MARKERS):
            scores["RELATED_DOCS_EXPLAIN"] += 8
        if self._has_http_path(text) or any(marker in text for marker in self._API_MARKERS):
            scores["API_METHOD_EXPLAIN"] += 6
        if scores["RELATED_DOCS_EXPLAIN"] > 0 and scores["API_METHOD_EXPLAIN"] > 0:
            scores["API_METHOD_EXPLAIN"] -= 2
        if any(marker in text for marker in self._ENTITY_MARKERS):
            scores["ENTITY_EXPLAIN"] += 5
        if self._has_entity_like_camel_token(source):
            scores["ENTITY_EXPLAIN"] += 3
        if self._looks_like_entity_question(text, source):
            scores["ENTITY_EXPLAIN"] += 2
        if any(marker in text for marker in self._NATURAL_ENTITY_MARKERS):
            scores["ENTITY_EXPLAIN"] += 3
        if any(marker in text for marker in self._COMPONENT_MARKERS):
            scores["COMPONENT_EXPLAIN"] += 5
        if any(marker in text for marker in self._FLOW_MARKERS):
            scores["SYSTEM_FLOW_EXPLAIN"] += 5
        if any(marker in text for marker in self._NATURAL_FLOW_MARKERS):
            scores["SYSTEM_FLOW_EXPLAIN"] += 3
        if any(marker in text for marker in self._GENERAL_MARKERS):
            scores["GENERIC_QA"] += 6
        if not any(scores.values()):
            scores["COMPONENT_EXPLAIN"] = 1
            scores["GENERIC_QA"] = 1
        ranked = sorted(scores.items(), key=lambda item: (-item[1], item[0]))
        return [item for item in ranked if item[1] > 0]

    def _detect_openapi(self, text: str) -> str:
        markers = ("request", "response", "schema", "parameters", "fragment")
        if any(marker in text for marker in markers):
            return "OPENAPI_FRAGMENT_GENERATE"
        return "OPENAPI_METHOD_GENERATE"

    def _has_http_path(self, text: str) -> bool:
        return any(token.startswith("/") and len(token) > 1 for token in text.split())

    def _has_entity_like_camel_token(self, raw: str) -> bool:
        return bool(self._ENTITY_LIKE_TOKEN_RE.search(raw or ""))

    def _looks_like_entity_question(self, text: str, raw: str) -> bool:
        if not any(marker in text for marker in ("что такое", "что за", "как используется")):
            return False
        return bool(self._CAMEL_ENTITY_CONTEXT_RE.search(raw or ""))
