"""LLMs API namespace."""

from __future__ import annotations

from typing import Any

from goodmem._base import AsyncCRUDNamespace, CRUDNamespace
from goodmem._generated.models.create_llm_response import CreateLLMResponse
from goodmem._generated.models.list_llms_response import ListLLMsResponse
from goodmem._generated.models.llm_creation_request import LLMCreationRequest
from goodmem._generated.models.llm_response import LLMResponse
from goodmem._generated.models.llm_update_request import LLMUpdateRequest
from goodmem._registries import LLM_MODEL_REGISTRY
from goodmem._schema_bridge import build_api_key_credentials

_PROVIDER_ENDPOINT_MAP = {
    "OPENAI": "https://api.openai.com/v1",
    "VLLM": None,  # user must provide
}


def _apply_llm_defaults(kwargs: dict[str, Any]) -> dict[str, Any]:
    """Apply model registry defaults and api_key convenience."""
    model_id = kwargs.get("model_identifier")
    if model_id and model_id in LLM_MODEL_REGISTRY:
        defaults = LLM_MODEL_REGISTRY[model_id]
        for key, value in defaults.items():
            kwargs.setdefault(key, value)
        pt = kwargs.get("provider_type")
        if pt and "endpoint_url" not in kwargs:
            ep = _PROVIDER_ENDPOINT_MAP.get(pt)
            if ep:
                kwargs["endpoint_url"] = ep

    api_key = kwargs.pop("api_key", None)
    if api_key:
        kwargs.setdefault("credentials", build_api_key_credentials(api_key))

    return kwargs


class LlmsAPI(CRUDNamespace):
    _base_path = "/v1/llms"
    _create_model = LLMCreationRequest
    _update_model = LLMUpdateRequest
    _response_model = LLMResponse
    _list_response_model = ListLLMsResponse
    _list_items_field = "llms"

    def create(self, **kwargs: Any) -> LLMResponse:
        """Create an LLM. Model registry auto-infers provider_type, max_context_length, etc."""
        kwargs = _apply_llm_defaults(kwargs)
        body = self._create_model.model_validate(kwargs)
        resp = self._http.post(
            self._base_path,
            json=body.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        from goodmem.errors import raise_for_status

        raise_for_status(resp)
        envelope = CreateLLMResponse.model_validate(resp.json())
        return envelope.llm


class AsyncLlmsAPI(AsyncCRUDNamespace):
    _base_path = "/v1/llms"
    _create_model = LLMCreationRequest
    _update_model = LLMUpdateRequest
    _response_model = LLMResponse
    _list_response_model = ListLLMsResponse
    _list_items_field = "llms"

    async def create(self, **kwargs: Any) -> LLMResponse:
        kwargs = _apply_llm_defaults(kwargs)
        body = self._create_model.model_validate(kwargs)
        resp = await self._http.post(
            self._base_path,
            json=body.model_dump(by_alias=True, exclude_unset=True),
            headers=self._headers,
        )
        from goodmem.errors import raise_for_status

        raise_for_status(resp)
        envelope = CreateLLMResponse.model_validate(resp.json())
        return envelope.llm
