"""
模型客户端工厂类

通过注册表机制动态创建客户端实例，新增 provider 只需在注册表中添加映射。
"""

import os
from typing import Dict, Type

from core.config import AppConfig, ProviderConfig, ModelConfig
from .base import BaseModelClient
from .openai_client import OpenAIClient
from .anthropic_client import AnthropicClient
from .minimax_client import MinimaxClient
from .glm_client import GLMClient
from .google_client import GoogleClient


class ModelClientFactory:
    """模型客户端工厂类，根据配置创建对应的客户端实例"""

    # provider_type → 客户端类 映射
    _CLIENT_REGISTRY: Dict[str, Type[BaseModelClient]] = {
        "openai": OpenAIClient,
        "anthropic": AnthropicClient,
        "minimax": MinimaxClient,
        "glm": GLMClient,
        "google": GoogleClient,
    }

    # provider_type → 环境变量名 映射
    _ENV_KEY_MAP: Dict[str, str] = {
        "openai": "OPENAI_API_KEY",
        "anthropic": "ANTHROPIC_API_KEY",
        "minimax": "MINIMAX_API_KEY",
        "glm": "ZHIPU_API_KEY",
        "google": "GEMINI_API_KEY",
    }

    @staticmethod
    def create_client_from_model(
        model_name: str,
        config: AppConfig,
    ) -> BaseModelClient:
        """
        根据模型名称和配置创建客户端实例

        Args:
            model_name: 模型名称，如 "anthropic/claude-opus-4-6"
            config: 应用配置

        Returns:
            BaseModelClient 实例

        Raises:
            ValueError: 模型或 provider 未定义
        """
        provider_section = config.provider

        # 查找模型配置
        model_config = provider_section.models.get(model_name)
        if not model_config:
            available = ", ".join(provider_section.models.keys())
            raise ValueError(
                f"未找到模型配置: {model_name}\n"
                f"可用模型: {available}"
            )

        # 查找 provider 配置
        provider_config = provider_section.providers.get(model_config.provider)
        if not provider_config:
            available = ", ".join(provider_section.providers.keys())
            raise ValueError(
                f"未找到 provider 配置: {model_config.provider}\n"
                f"可用 provider: {available}"
            )

        return ModelClientFactory._create_client(
            provider_config=provider_config,
            model_config=model_config,
        )

    @staticmethod
    def _create_client(
        provider_config: ProviderConfig,
        model_config: ModelConfig,
    ) -> BaseModelClient:
        """
        根据 provider 类型创建具体客户端

        Args:
            provider_config: Provider 连接配置
            model_config: 模型配置

        Returns:
            BaseModelClient 实例
        """
        provider_type = provider_config.type.lower()

        # 获取 API key（优先使用配置，其次环境变量）
        api_key = provider_config.api_key
        if not api_key:
            env_var = ModelClientFactory._ENV_KEY_MAP.get(provider_type)
            if env_var:
                api_key = os.getenv(env_var)

        kwargs = {
            "model": model_config.model,
            "api_key": api_key,
            "base_url": provider_config.base_url,
            "temperature": model_config.temperature,
            "max_tokens": model_config.max_tokens,
            # context_window 不再从配置传入，由 BaseModelClient 从 models.py 自动获取
        }

        client_cls = ModelClientFactory._CLIENT_REGISTRY.get(provider_type)
        if not client_cls:
            supported = ", ".join(ModelClientFactory._CLIENT_REGISTRY.keys())
            raise ValueError(
                f"不支持的 provider 类型: {provider_type}\n"
                f"支持的类型: {supported}"
            )

        return client_cls(**kwargs)
