"""Flat LLM settings from environment (single active provider for Normbase/runtime)."""
from __future__ import annotations

from pydantic import AliasChoices, Field, model_validator
from pydantic_settings import BaseSettings, SettingsConfigDict

_NO_API_KEY = frozenset({"ollama", "local", "embedding"})


class LLMSettings(BaseSettings):
    """One provider name + credentials; optional model overrides."""

    llm_provider: str = Field(
        validation_alias=AliasChoices("LLM_PROVIDER", "NORMBASE_LLM_PROVIDER"),
    )
    llm_api_key: str = Field(
        default="",
        validation_alias=AliasChoices("LLM_API_KEY", "NORMBASE_LLM_API_KEY"),
    )
    llm_model: str | None = Field(
        default=None,
        validation_alias=AliasChoices("LLM_MODEL", "NORMBASE_LLM_MODEL"),
    )
    llm_embedding_model: str | None = Field(
        default=None,
        validation_alias=AliasChoices(
            "LLM_EMBEDDING_MODEL", "NORMBASE_LLM_EMBEDDING_MODEL"
        ),
    )
    llm_base_url: str | None = Field(
        default=None,
        validation_alias=AliasChoices("LLM_BASE_URL", "NORMBASE_LLM_BASE_URL"),
    )
    llm_azure_endpoint: str | None = Field(
        default=None,
        validation_alias=AliasChoices(
            "LLM_AZURE_ENDPOINT", "NORMBASE_LLM_AZURE_ENDPOINT"
        ),
    )

    model_config = SettingsConfigDict(env_file=".env", extra="ignore")

    @model_validator(mode="after")
    def _require_credentials(self) -> LLMSettings:
        name = self.llm_provider.strip()
        if not name:
            raise ValueError("LLM_PROVIDER is empty")
        if name in _NO_API_KEY:
            return self
        if name == "azure":
            if not (self.llm_api_key or "").strip():
                raise ValueError("LLM_API_KEY is required for azure")
            if not (self.llm_azure_endpoint or "").strip():
                raise ValueError(
                    "LLM_AZURE_ENDPOINT is required for azure "
                    "(Azure resource URL, not the same as LLM_BASE_URL)"
                )
            return self
        if not (self.llm_api_key or "").strip():
            raise ValueError(f"LLM_API_KEY is required for provider {name!r}")
        return self


def settings_to_provider_block(s: LLMSettings) -> dict:
    """Build the config dict passed to create_provider."""
    block: dict = {}
    if (s.llm_api_key or "").strip():
        block["api_key"] = s.llm_api_key.strip()
    if s.llm_model and str(s.llm_model).strip():
        block["model"] = s.llm_model.strip()
    if s.llm_embedding_model and str(s.llm_embedding_model).strip():
        block["embedding_model"] = s.llm_embedding_model.strip()
    if s.llm_base_url and str(s.llm_base_url).strip():
        block["base_url"] = s.llm_base_url.strip()
    if s.llm_provider == "azure" and (s.llm_azure_endpoint or "").strip():
        block["endpoint"] = s.llm_azure_endpoint.strip()
    return block
