"""
Mode Router.
[AC-AISVC-RES-09~15] 模式路由器。
"""

import logging
from dataclasses import dataclass

from app.services.retrieval.strategy.config import ModeRouterConfig, RuntimeMode
from app.services.retrieval.strategy.pipeline_base import PipelineResult

logger = logging.getLogger(__name__)


@dataclass
class ModeDecision:
    """模式决策结果。"""
    mode: RuntimeMode
    reason: str
    confidence: float | None = None
    complexity_score: float | None = None


class ModeRouter:
    """
    模式路由器。【AC-AISVC-RES-09~15】
    
    职责：
    1. 根据 rag_runtime_mode 选择 direct/react/auto 模式
    2. auto 模式下根据复杂度与置信度自动选择路由
    3. direct 低置信度时触发 react 回退
    """
    
    def __init__(self, config: ModeRouterConfig | None = None):
        self._config = config or ModeRouterConfig()
    
    def decide(
        self,
        query: str,
        confidence: float | None = None,
        complexity_score: float | None = None,
    ) -> ModeDecision:
        """决定使用哪种模式。【AC-AISVC-RES-09~13】"""
        if self._config.runtime_mode == RuntimeMode.REACT:
            return ModeDecision(mode=RuntimeMode.REACT, reason="runtime_mode=react")
        
        if self._config.runtime_mode == RuntimeMode.DIRECT:
            return ModeDecision(mode=RuntimeMode.DIRECT, reason="runtime_mode=direct")
        
        calculated_complexity = complexity_score or self._calculate_complexity(query)
        
        if self._should_use_direct(query, confidence, calculated_complexity):
            return ModeDecision(
                mode=RuntimeMode.DIRECT,
                reason="auto: short_query_high_confidence",
                confidence=confidence,
                complexity_score=calculated_complexity,
            )
        
        return ModeDecision(
            mode=RuntimeMode.REACT,
            reason="auto: complex_or_low_confidence",
            confidence=confidence,
            complexity_score=calculated_complexity,
        )
    
    def should_fallback_to_react(self, direct_result: PipelineResult) -> bool:
        """判断是否应该从 direct 回退到 react。【AC-AISVC-RES-14】"""
        if not self._config.direct_fallback_on_low_confidence:
            return False
        if direct_result.is_empty:
            return True
        max_score = direct_result.retrieval_result.max_score
        if max_score < 0.3:
            return True
        if direct_result.retrieval_result.hit_count < 2:
            return True
        return False
    
    def _should_use_direct(
        self, query: str, confidence: float | None, complexity_score: float
    ) -> bool:
        if len(query) <= self._config.short_query_threshold:
            if confidence and confidence >= self._config.react_trigger_confidence_threshold:
                return True
        if confidence and confidence < self._config.react_trigger_confidence_threshold:
            return False
        if complexity_score >= self._config.react_trigger_complexity_score:
            return False
        return True
    
    def _calculate_complexity(self, query: str) -> float:
        score = 0.0
        if len(query) > 50:
            score += 0.2
        if len(query) > 100:
            score += 0.2
        condition_words = ["和", "或", "但是", "如果", "同时", "并且", "或者", "以及"]
        for word in condition_words:
            if word in query:
                score += 0.1
        return min(score, 1.0)
    
    def get_config(self) -> ModeRouterConfig:
        return self._config
    
    def update_config(self, config: ModeRouterConfig) -> None:
        self._config = config


_mode_router: ModeRouter | None = None


def get_mode_router() -> ModeRouter:
    global _mode_router
    if _mode_router is None:
        _mode_router = ModeRouter()
    return _mode_router
