"""
llm_smart_router.providers.mistral
----------------------------------

Mistral AI 供應商適配器

實作 Mistral AI 的模型查詢與替換邏輯。
支援 Mistral 系列模型,包含 Small, Medium, Large 階層與程式碼專用模型。
"""

import re
from typing import List, Dict
from .base import BaseProvider
from ..exceptions import ProviderAPIError


class MistralProvider(BaseProvider):
    """
    Mistral AI 供應商適配器
    
    API 端點: https://api.mistral.ai/v1/models
    命名規範: mistral-{tier}-{version} 或 {variant}-{version}
    範例: mistral-small-3.1, mistral-medium-3, codestral-2501, devstral-2
    
    階層分類:
    - Small: 小型模型
    - Medium: 中型模型
    - Large: 大型模型
    
    特殊變體:
    - Codestral: 程式碼專用模型
    - Devstral: 開發者專用模型
    """
    
    API_BASE = "https://api.mistral.ai/v1"
    
    async def list_models(self) -> List[str]:
        """
        查詢 Mistral AI 可用模型清單
        
        使用 Mistral API 的 /v1/models 端點 (OpenAI 相容格式)。
        
        Returns:
            模型名稱列表
        
        Raises:
            ProviderAPIError: 當 API 查詢失敗時拋出
        """
        try:
            import os
            
            api_key = os.environ.get("MISTRAL_API_KEY")
            if not api_key:
                raise ProviderAPIError("請設定 MISTRAL_API_KEY 環境變數")
            
            response = await self.client.get(
                f"{self.API_BASE}/models",
                headers={"Authorization": f"Bearer {api_key}"}
            )
            response.raise_for_status()
            data = response.json()
            return [m["id"] for m in data.get("data", [])]
        except Exception as e:
            raise ProviderAPIError(f"查詢 Mistral 模型清單失敗: {e}")
    
    def _extract_family(self, model_name: str) -> Dict[str, str]:
        """
        提取 Mistral 模型的家族特徵
        
        從模型名稱中識別階層、變體與基礎名稱。
        
        Args:
            model_name: 模型名稱
        
        Returns:
            家族特徵字典,包含 "base" 與 "tier"
        
        Examples:
            >>> _extract_family("mistral-small-3.1")
            {"base": "mistral", "tier": "small"}
            >>> _extract_family("codestral-2501")
            {"base": "codestral", "tier": "code"}
            >>> _extract_family("devstral-2")
            {"base": "devstral", "tier": "code"}
        """
        model_lower = model_name.lower()
        
        # 檢查是否為 code 專用模型
        if "codestral" in model_lower or "devstral" in model_lower:
            base = model_name.split("-")[0].lower()  # codestral 或 devstral
            return {"base": base, "tier": "code"}
        
        # 一般 Mistral 模型
        tiers = ["small", "medium", "large"]
        tier = "unknown"
        for t in tiers:
            if t in model_lower:
                tier = t
                break
        
        return {
            "base": "mistral",
            "tier": tier
        }
    
    def _select_latest(self, candidates: List[str]) -> str:
        """
        從 Mistral 候選模型中選擇最新版本
        
        選擇策略:
        1. 提取版本號 (支援 3.1, 2501 等格式)
        2. 按版本號排序
        3. 選擇版本號最高的模型
        
        Args:
            candidates: 候選模型列表
        
        Returns:
            最新版本的模型名稱
        """
        def version_key(model: str):
            """生成排序鍵值"""
            # 提取版本號 (如 3.1, 2501)
            match = re.search(r'(\d+\.?\d*)', model)
            return float(match.group(1)) if match else 0.0
        
        return max(candidates, key=version_key)
