"""LLM Config - 配置加载"""

from dataclasses import dataclass, field
from typing import Any

import yaml

from agentkit.llm.retry import CircuitBreakerConfig, RetryConfig


@dataclass
class ProviderConfig:
    """Provider 配置"""

    api_key: str
    base_url: str
    models: dict[str, dict[str, Any]] = field(default_factory=dict)
    type: str = "openai"  # "openai" | "anthropic" | "gemini"
    max_tokens: int = 4096  # Anthropic: default max_tokens
    timeout: float = 120.0  # Anthropic: request timeout
    retry: RetryConfig | None = None
    circuit_breaker: CircuitBreakerConfig | None = None


@dataclass
class LLMConfig:
    """LLM 配置"""

    providers: dict[str, ProviderConfig] = field(default_factory=dict)
    model_aliases: dict[str, str] = field(default_factory=dict)
    fallbacks: dict[str, list[str]] = field(default_factory=dict)

    @classmethod
    def from_yaml(cls, path: str) -> "LLMConfig":
        """从 YAML 文件加载配置"""
        with open(path, encoding="utf-8") as f:
            data = yaml.safe_load(f)
        return cls.from_dict(data or {})

    @classmethod
    def from_dict(cls, data: dict) -> "LLMConfig":
        """从字典加载配置"""
        providers = {}
        for name, pconf in data.get("providers", {}).items():
            retry = None
            retry_data = pconf.get("retry")
            if retry_data:
                retry = RetryConfig(
                    max_retries=retry_data.get("max_retries", 3),
                    base_delay=retry_data.get("base_delay", 1.0),
                    max_delay=retry_data.get("max_delay", 30.0),
                    exponential_base=retry_data.get("exponential_base", 2.0),
                )

            circuit_breaker = None
            cb_data = pconf.get("circuit_breaker")
            if cb_data:
                circuit_breaker = CircuitBreakerConfig(
                    failure_threshold=cb_data.get("failure_threshold", 5),
                    recovery_timeout=cb_data.get("recovery_timeout", 60.0),
                    half_open_max=cb_data.get("half_open_max", 1),
                )

            providers[name] = ProviderConfig(
                api_key=pconf.get("api_key", ""),
                base_url=pconf.get("base_url", ""),
                models=pconf.get("models", {}),
                type=pconf.get("type", "openai"),
                max_tokens=pconf.get("max_tokens", 4096),
                timeout=pconf.get("timeout", 120.0),
                retry=retry,
                circuit_breaker=circuit_breaker,
            )
        return cls(
            providers=providers,
            model_aliases=data.get("model_aliases", {}),
            fallbacks=data.get("fallbacks", {}),
        )
