from __future__ import annotations

# standard
import os

# third party
# custom
from .base import BaseEngine
from .providers.anthropic import AnthropicEngine
from .providers.google import GoogleEngine
from .providers.openai import OpenAIEngine

_OPENAI_COMPATIBLE: dict[str, str] = {
    "openai": "https://api.openai.com/v1",
    "deepseek": "https://api.deepseek.com/v1",
    "moonshot": "https://api.moonshot.ai/v1",
    "xai": "https://api.x.ai/v1",
}


def get_engine(
    provider: str,
    model: str,
    api_key: str | None = None,
    max_tokens: int = 8192,
    thinking_budget: int | None = None,
    reasoning_effort: str | None = None,
) -> BaseEngine:
    """Return the correct engine instance for the given provider.

    ``api_key`` is used as-is when provided. Otherwise the env var
    ``<PROVIDER>_API_KEY`` (e.g. ``ANTHROPIC_API_KEY``) is tried. A
    ``ValueError`` is raised when neither is set.

    ``thinking_budget`` controls extended thinking for Anthropic and Google
    (both default to max when not set). ``reasoning_effort`` controls the
    reasoning level for OpenAI-compatible providers that support it
    (``"low"``, ``"medium"``, ``"high"``; ``None`` = not sent).
    """
    p = provider.lower()

    resolved_key = api_key or os.environ.get(f"{p.upper()}_API_KEY")
    if not resolved_key:
        raise ValueError(
            f"No API key for provider '{provider}'. "
            f"Pass api_key= or set the {p.upper()}_API_KEY environment variable."
        )

    if p in _OPENAI_COMPATIBLE:
        return OpenAIEngine(
            provider=p,
            model=model,
            api_key=resolved_key,
            base_url=_OPENAI_COMPATIBLE[p],
            max_tokens=max_tokens,
            reasoning_effort=reasoning_effort,
        )

    if p == "anthropic":
        return AnthropicEngine(
            model=model,
            api_key=resolved_key,
            max_tokens=max_tokens,
            thinking_budget=thinking_budget,
        )

    if p == "google":
        return GoogleEngine(
            model=model,
            api_key=resolved_key,
            max_tokens=max_tokens,
            thinking_budget=thinking_budget,
        )

    raise ValueError(
        f"Unknown provider '{provider}'. "
        f"Supported: {', '.join(sorted({*_OPENAI_COMPATIBLE, 'anthropic', 'google'}))}"
    )
