"""
Factory for creating LLM adapters by provider name.
"""

from typing import Optional, Dict, Any

from markitect.prompts.execution.llm_adapter import LLMAdapter
from markitect.llm.exceptions import LLMConfigurationError

# Lazy imports to avoid pulling in every adapter at module load time.
_PROVIDERS: Dict[str, str] = {
    "openrouter": "markitect.llm.openrouter.OpenRouterAdapter",
    "claude-code": "markitect.llm.claude_code.ClaudeCodeAdapter",
}


def create_adapter(
    provider: str = "openrouter",
    model: Optional[str] = None,
    api_key: Optional[str] = None,
    system_prompt: Optional[str] = None,
    **kwargs: Any,
) -> LLMAdapter:
    """Instantiate an :class:`LLMAdapter` for the given *provider*.

    Args:
        provider: ``"openrouter"`` or ``"claude-code"``.
        model: Model name (passed to the adapter constructor).
        api_key: Explicit API key (OpenRouter only).
        system_prompt: Optional system prompt (OpenRouter only).
        **kwargs: Extra keyword arguments forwarded to the adapter.

    Returns:
        A ready-to-use :class:`LLMAdapter` instance.

    Raises:
        LLMConfigurationError: If *provider* is not recognised.
    """
    if provider not in _PROVIDERS:
        known = ", ".join(sorted(_PROVIDERS))
        raise LLMConfigurationError(
            f"Unknown LLM provider {provider!r}. Choose from: {known}",
            context={"provider": provider},
        )

    # Lazy import
    fqn = _PROVIDERS[provider]
    module_path, class_name = fqn.rsplit(".", 1)
    import importlib
    mod = importlib.import_module(module_path)
    cls = getattr(mod, class_name)

    if provider == "openrouter":
        return cls(model=model, api_key=api_key, system_prompt=system_prompt, **kwargs)
    elif provider == "claude-code":
        return cls(model=model, **kwargs)
    else:
        return cls(**kwargs)  # pragma: no cover
