from __future__ import annotations

from app.modules.rag.intent_router_v2.models import ConversationState, IntentDecision


class ConversationPolicy:
    _SWITCH_MARKERS = (
        "переключ",
        "new task",
        "switch to",
        "instead",
    )
    _FOLLOWUP_MARKERS = (
        "теперь",
        "а теперь",
        "давай теперь",
        "дальше",
        "потом",
        "следом",
        "next",
        "then",
    )
    _DOCS_SIGNALS = ("документац", "readme", "docs/", ".md")
    _CODE_SIGNALS = ("по коду", "класс", "метод", "файл", "блок кода", "function", "class")

    def resolve(self, decision: IntentDecision, user_query: str, conversation_state: ConversationState) -> tuple[str, str]:
        active_intent = conversation_state.active_intent
        if active_intent is None:
            return decision.intent, "START"
        followup_likely = self._is_followup_likely(user_query)
        if active_intent == decision.intent:
            return active_intent, "FOLLOWUP_LIKELY" if followup_likely else "CONTINUE"
        if self._has_explicit_switch(user_query):
            return decision.intent, "SWITCH"
        if self._is_hard_mismatch(active_intent, decision.intent, user_query):
            return decision.intent, "SWITCH"
        if followup_likely:
            return active_intent, "FOLLOWUP_LIKELY"
        return active_intent, "CONTINUE"

    def _has_explicit_switch(self, user_query: str) -> bool:
        text = " ".join((user_query or "").lower().split())
        return any(marker in text for marker in self._SWITCH_MARKERS)

    def _is_followup_likely(self, user_query: str) -> bool:
        text = " ".join((user_query or "").lower().split())
        return any(marker in text for marker in self._FOLLOWUP_MARKERS)

    def _is_hard_mismatch(self, active_intent: str, candidate_intent: str, user_query: str) -> bool:
        if active_intent == candidate_intent:
            return False
        text = " ".join((user_query or "").lower().split())
        if candidate_intent == "GENERATE_DOCS_FROM_CODE":
            return True
        if candidate_intent == "DOCS_QA":
            return any(signal in text for signal in self._DOCS_SIGNALS)
        if candidate_intent == "CODE_QA" and active_intent == "DOCS_QA":
            return any(signal in text for signal in self._CODE_SIGNALS)
        return False
