"""
llm_smart_router.providers.anthropic
------------------------------------

Claude (Anthropic) 供應商適配器

實作 Anthropic 的模型查詢與替換邏輯。
支援 Claude 系列模型,包含 Haiku, Sonnet, Opus 階層。
"""

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


class AnthropicProvider(BaseProvider):
    """
    Anthropic (Claude) 供應商適配器
    
    API 端點: https://api.anthropic.com/v1/models
    命名規範: claude-{version}-{tier}[-{variant}]
    範例: claude-4-5-haiku-20250101, claude-3-5-sonnet
    
    階層分類:
    - Haiku: 快速輕量級模型
    - Sonnet: 平衡型模型
    - Opus: 最強大模型
    """
    
    API_BASE = "https://api.anthropic.com/v1"
    
    async def list_models(self) -> List[str]:
        """
        查詢 Anthropic 可用模型清單
        
        使用 Anthropic API 的 /v1/models 端點查詢所有可用模型。
        注意: 此方法需要使用者已設定 ANTHROPIC_API_KEY 環境變數。
        
        Returns:
            模型名稱列表
        
        Raises:
            ProviderAPIError: 當 API 查詢失敗時拋出
        """
        try:
            # 注意: 實際使用時需要 API Key,這裡簡化處理
            # 使用者應在自己的程式碼中設定 anthropic.api_key
            response = await self.client.get(
                f"{self.API_BASE}/models",
                headers={
                    "x-api-key": "placeholder",  # 實際由使用者 SDK 處理
                    "anthropic-version": "2023-06-01"
                }
            )
            response.raise_for_status()
            data = response.json()
            return [m["id"] for m in data.get("data", [])]
        except Exception as e:
            raise ProviderAPIError(f"查詢 Anthropic 模型清單失敗: {e}")
    
    def _extract_family(self, model_name: str) -> Dict[str, str]:
        """
        提取 Claude 模型的家族特徵
        
        從模型名稱中識別階層 (haiku/sonnet/opus) 與基礎名稱 (claude)。
        
        Args:
            model_name: 模型名稱
        
        Returns:
            家族特徵字典,包含 "base" 與 "tier"
        
        Examples:
            >>> _extract_family("claude-3-5-haiku-20241022")
            {"base": "claude", "tier": "haiku"}
            >>> _extract_family("claude-4-opus")
            {"base": "claude", "tier": "opus"}
        """
        model_lower = model_name.lower()
        
        # 識別階層
        tiers = ["haiku", "sonnet", "opus"]
        tier = "unknown"
        for t in tiers:
            if t in model_lower:
                tier = t
                break
        
        return {
            "base": "claude",
            "tier": tier
        }
    
    def _select_latest(self, candidates: List[str]) -> str:
        """
        從 Claude 候選模型中選擇最新版本
        
        選擇策略:
        1. 優先選擇非 preview 版本 (穩定版)
        2. 提取版本號 (如 3-5, 4-5) 並排序
        3. 若版本相同,比較日期戳記 (如 20241022)
        4. 選擇版本號最高且日期最新的模型
        
        Args:
            candidates: 候選模型列表
        
        Returns:
            最新版本的模型名稱
        """
        # 過濾 preview 版本
        stable = [m for m in candidates if "preview" not in m.lower()]
        if not stable:
            stable = candidates
        
        def version_key(model: str):
            """生成排序鍵值"""
            # 提取版本號 (如 "claude-4-5-haiku" -> (4, 5))
            version_match = re.search(r'claude-(\d+)-(\d+)', model.lower())
            if version_match:
                major, minor = version_match.groups()
                version = (int(major), int(minor))
            else:
                version = (0, 0)
            
            # 提取日期戳記 (如 "20241022")
            date_match = re.search(r'(\d{8})', model)
            date = int(date_match.group(1)) if date_match else 0
            
            # 穩定性分數: 有日期戳記的視為穩定版
            stability = 1 if date > 0 else 0
            
            return (version, stability, date)
        
        return max(stable, key=version_key)
