"""
Provider definitions for LLM API connections.

Defines supported LLM providers with their configuration requirements,
environment variable names, and available models.
"""

from dataclasses import dataclass, field


@dataclass
class ProviderDefinition:
    """Definition of an LLM provider"""

    name: str  # Internal name (e.g., "openai")
    display_name: str  # Display name (e.g., "OpenAI")
    env_vars: list[str]  # Required environment variables
    models: list[str]  # Example models
    description: str  # Short description
    test_model: str = ""  # Model to use for validation
    extra_vars: list[str] = field(default_factory=list)  # Optional extra vars (e.g., endpoint)

    def __post_init__(self) -> None:
        """Set default test model if not specified"""
        if not self.test_model and self.models:
            self.test_model = self.models[0]


PROVIDERS: dict[str, ProviderDefinition] = {
    "openai": ProviderDefinition(
        name="openai",
        display_name="OpenAI",
        env_vars=["OPENAI_API_KEY"],
        models=["gpt-4o", "gpt-4o-mini", "o1", "o1-mini"],
        description="GPT-4o, o1 reasoning models",
        test_model="gpt-4o-mini",
    ),
    "anthropic": ProviderDefinition(
        name="anthropic",
        display_name="Anthropic",
        env_vars=["ANTHROPIC_API_KEY"],
        models=["claude-3-5-sonnet-20241022", "claude-3-opus-20240229"],
        description="Claude 3.5 Sonnet, Opus",
        test_model="claude-3-5-sonnet-20241022",
    ),
    "xai": ProviderDefinition(
        name="xai",
        display_name="xAI",
        env_vars=["XAI_API_KEY"],
        models=["grok-2", "grok-2-mini"],
        description="Grok-2, Grok-2-mini",
        test_model="grok-2-mini",
    ),
    "gemini": ProviderDefinition(
        name="gemini",
        display_name="Google Gemini",
        env_vars=["GEMINI_API_KEY"],
        models=["gemini-2.0-flash", "gemini-1.5-pro"],
        description="Gemini 2.0 Flash, 1.5 Pro",
        test_model="gemini-2.0-flash",
    ),
    "groq": ProviderDefinition(
        name="groq",
        display_name="Groq",
        env_vars=["GROQ_API_KEY"],
        models=["llama-3.3-70b-versatile", "mixtral-8x7b-32768"],
        description="Ultra-fast inference",
        test_model="llama-3.3-70b-versatile",
    ),
    "openrouter": ProviderDefinition(
        name="openrouter",
        display_name="OpenRouter",
        env_vars=["OPENROUTER_API_KEY"],
        models=["openai/gpt-4o", "anthropic/claude-3.5-sonnet"],
        description="100+ models, single API",
        test_model="openai/gpt-4o-mini",
    ),
    "azure": ProviderDefinition(
        name="azure",
        display_name="Azure OpenAI",
        env_vars=["AZURE_OPENAI_API_KEY"],
        models=["gpt-4o", "gpt-4o-mini"],
        description="Azure-hosted OpenAI models",
        test_model="gpt-4o-mini",
        extra_vars=["AZURE_OPENAI_ENDPOINT"],
    ),
    "local": ProviderDefinition(
        name="local",
        display_name="Local LLM",
        env_vars=[],  # No API key required for most local servers
        models=["llama3", "mistral", "codellama", "custom"],
        description="LM Studio, Ollama, LocalAI, vLLM",
        test_model="",  # Will use whatever model is configured
        extra_vars=["LOCAL_LLM_ENDPOINT", "LOCAL_LLM_MODEL"],
    ),
}


def get_provider(name: str) -> ProviderDefinition | None:
    """Get provider definition by name"""
    return PROVIDERS.get(name.lower())


def list_providers() -> list[ProviderDefinition]:
    """Get list of all provider definitions"""
    return list(PROVIDERS.values())


def get_provider_names() -> list[str]:
    """Get list of provider names"""
    return list(PROVIDERS.keys())
