"""
llm_smart_router.providers.openai
---------------------------------

GPT (OpenAI) 供應商適配器

實作 OpenAI 的模型查詢與替換邏輯。
支援 GPT 系列模型 (gpt-4, gpt-5 等) 及 o 系列推理模型 (o1, o3, o4 等)。
GPT 系列包含 Nano, Mini, Base, Pro, Ultimate 階層。
"""

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


class OpenAIProvider(BaseProvider):
    """
    OpenAI (GPT) 供應商適配器
    
    API 端點: https://api.openai.com/v1/models
    命名規範: 
      - GPT 系列: gpt-{version}[-{tier}][-{date}] (如 gpt-5-mini, gpt-5.2-pro)
      - o 系列: o{number}[-{variant}] (如 o1, o3-pro, o4-mini)
    
    階層分類:
    - Nano: 極小模型
    - Mini: 小型模型
    - Base: 基礎模型 (無後綴)
    - Pro: 專業模型
    - Ultimate: 最強大模型
    """
    
    API_BASE = "https://api.openai.com/v1"
    
    async def list_models(self) -> List[str]:
        """
        查詢 OpenAI 可用模型清單
        
        使用 OpenAI API 的 /v1/models 端點查詢所有模型,
        並過濾出 gpt- 開頭的模型。
        
        Returns:
            模型名稱列表 (僅包含 GPT 系列)
        
        Raises:
            ProviderAPIError: 當 API 查詢失敗時拋出
        """
        try:
            import os
            
            api_key = os.environ.get("OPENAI_API_KEY")
            if not api_key:
                raise ProviderAPIError("請設定 OPENAI_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()
            
            # 返回 GPT 系列和 o 系列模型
            return [
                m["id"] for m in data.get("data", []) 
                if m["id"].startswith("gpt-") or re.match(r'^o\d+', m["id"])
            ]
        except Exception as e:
            raise ProviderAPIError(f"查詢 OpenAI 模型清單失敗: {e}")
    
    def _extract_family(self, model_name: str) -> Dict[str, str]:
        """
        提取 GPT 模型的家族特徵
        
        從模型名稱中識別階層與基礎版本號。
        
        Args:
            model_name: 模型名稱
        
        Returns:
            家族特徵字典,包含 "base" 與 "tier"
        
        Examples:
            >>> _extract_family("gpt-5-mini")
            {"base": "gpt-5", "tier": "mini"}
            >>> _extract_family("gpt-5.2-pro")
            {"base": "gpt-5", "tier": "pro"}
            >>> _extract_family("gpt-5")
            {"base": "gpt-5", "tier": "base"}
        """
        model_lower = model_name.lower()
        
        # 提取階層
        tiers = ["nano", "mini", "base", "pro", "ultimate"]
        tier = "base"  # 預設為 base (無後綴的模型)
        for t in tiers:
            if t in model_lower and t != "base":
                tier = t
                break
        
        # 提取基礎版本 (如 gpt-5, gpt-4.1)
        match = re.search(r'(gpt-\d+\.?\d*)', model_lower)
        base = match.group(1) if match else "gpt"
        
        return {
            "base": base,
            "tier": tier
        }
    
    def _select_latest(self, candidates: List[str]) -> str:
        """
        從 GPT 候選模型中選擇最新版本
        
        選擇策略:
        1. 提取主版本號 (如 5.2)
        2. 提取日期戳記 (如果有)
        3. 按版本號 > 日期戳記排序
        4. 選擇最高版本
        
        Args:
            candidates: 候選模型列表
        
        Returns:
            最新版本的模型名稱
        """
        def version_key(model: str):
            """生成排序鍵值"""
            # 提取主版本 (如 5.2, 4.1)
            version_match = re.search(r'gpt-(\d+\.?\d*)', model.lower())
            version = float(version_match.group(1)) if version_match else 0.0
            
            # 提取日期 (如果有,如 20250101)
            date_match = re.search(r'(\d{8})', model)
            date = int(date_match.group(1)) if date_match else 0
            
            return (version, date)
        
        return max(candidates, key=version_key)
