"""
Strategy Router.
[AC-AISVC-RES-01~03] 策略路由器。
"""

import logging
from dataclasses import dataclass
from typing import Any

from app.services.retrieval.strategy.config import (
    RetrievalStrategyConfig,
    StrategyType,
)
from app.services.retrieval.strategy.default_pipeline import DefaultPipeline, get_default_pipeline
from app.services.retrieval.strategy.enhanced_pipeline import EnhancedPipeline, get_enhanced_pipeline
from app.services.retrieval.strategy.pipeline_base import BasePipeline

logger = logging.getLogger(__name__)


@dataclass
class RoutingDecision:
    """路由决策结果。"""
    strategy: StrategyType
    pipeline: BasePipeline
    reason: str
    grayscale_hit: bool = False


class StrategyRouter:
    """
    策略路由器。【AC-AISVC-RES-01~03】
    
    职责：
    1. 根据配置选择默认策略或增强策略
    2. 支持灰度发布（percentage/allowlist）
    3. 不影响正在运行的默认策略请求
    """
    
    def __init__(
        self,
        config: RetrievalStrategyConfig | None = None,
        default_pipeline: DefaultPipeline | None = None,
        enhanced_pipeline: EnhancedPipeline | None = None,
    ):
        self._config = config or RetrievalStrategyConfig()
        self._default_pipeline = default_pipeline
        self._enhanced_pipeline = enhanced_pipeline
    
    async def route(
        self, tenant_id: str, user_id: str | None = None
    ) -> RoutingDecision:
        """路由到合适的策略。【AC-AISVC-RES-01~03】"""
        if self._config.active_strategy == StrategyType.ENHANCED:
            pipeline = await self._get_enhanced_pipeline()
            return RoutingDecision(
                strategy=StrategyType.ENHANCED,
                pipeline=pipeline,
                reason="active_strategy=enhanced",
            )
        
        if self._config.grayscale.should_use_enhanced(tenant_id, user_id):
            pipeline = await self._get_enhanced_pipeline()
            return RoutingDecision(
                strategy=StrategyType.ENHANCED,
                pipeline=pipeline,
                reason="grayscale_hit",
                grayscale_hit=True,
            )
        
        pipeline = await self._get_default_pipeline()
        return RoutingDecision(
            strategy=StrategyType.DEFAULT,
            pipeline=pipeline,
            reason="default_strategy",
        )
    
    async def _get_default_pipeline(self) -> DefaultPipeline:
        if self._default_pipeline is None:
            self._default_pipeline = await get_default_pipeline()
        return self._default_pipeline
    
    async def _get_enhanced_pipeline(self) -> EnhancedPipeline:
        if self._enhanced_pipeline is None:
            self._enhanced_pipeline = await get_enhanced_pipeline()
        return self._enhanced_pipeline
    
    def get_config(self) -> RetrievalStrategyConfig:
        return self._config
    
    def update_config(self, config: RetrievalStrategyConfig) -> None:
        self._config = config
        logger.info(f"[StrategyRouter] Config updated: strategy={config.active_strategy.value}")


_strategy_router: StrategyRouter | None = None


def get_strategy_router() -> StrategyRouter:
    global _strategy_router
    if _strategy_router is None:
        _strategy_router = StrategyRouter()
    return _strategy_router


def set_strategy_router(router: StrategyRouter) -> None:
    """Set the global strategy router instance."""
    global _strategy_router
    _strategy_router = router
