"""Configuration models for SDK components."""

import json
import os

from pydantic import AliasChoices, BaseModel, Field

from ..exceptions import EnvironmentError


class EmbeddingServiceConfig(BaseModel):
    """Configuration model for Embedding Service."""

    endpoint: str = Field(..., description="Endpoint URL for the embedding service")
    modelServingName: str = Field(..., description="Name of the model serving instance")  # noqa: N815
    baseModelName: str = Field(..., description="Name of the base model used for embeddings")  # noqa: N815
    apiKey: str | None = Field(None, description="API key for the embedding service")  # noqa: N815


class RerankServiceConfig(BaseModel):
    """Configuration model for Rerank Service."""

    endpoint: str = Field(..., description="Endpoint URL for the rerank service")
    modelServingName: str = Field(..., description="Name of the model serving instance")  # noqa: N815
    baseModelName: str = Field(..., description="Name of the base model used for reranking")  # noqa: N815
    apiKey: str | None = Field(None, description="API key for the rerank service")  # noqa: N815


class OntologyServiceConfig(BaseModel):
    """Configuration model for Ontology Service."""

    endpoint: str = Field(..., description="Endpoint URL for the ontology service")
    token: str = Field(..., description="Authentication token for the ontology service")
    bceAccessKey: str | None = Field(  # noqa: N815
        None,
        validation_alias=AliasChoices("bceAccessKey", "x-bce-access-key"),
        description="BCE access key for ontology request headers",
    )
    bceSecurityKey: str | None = Field(  # noqa: N815
        None,
        validation_alias=AliasChoices("bceSecurityKey", "x-bce-security-key"),
        description="BCE security key for ontology request headers",
    )
    bceSecurityToken: str | None = Field(  # noqa: N815
        None,
        validation_alias=AliasChoices("bceSecurityToken", "x-bce-security-token"),
        description="BCE security token for ontology request headers",
    )


class ServiceConfig(BaseModel):
    """Configuration for Service."""

    embedding: EmbeddingServiceConfig | None = Field(None, description="Configuration for Embedding Service")
    rerank: RerankServiceConfig | None = Field(None, description="Configuration for Rerank Service")
    ontology: OntologyServiceConfig | None = Field(None, description="Configuration for Ontology Service")
    workspaceId: str | None = Field(None, description="Workspace id")  # noqa: N815


class Config(BaseModel):
    """Configuration model for SDK components."""

    service_config: ServiceConfig = Field(..., description="Configuration for Service")


# global config
_config_instance: Config | None = None


def get_global_config() -> Config:
    """Load and parse configuration from environment variables.

    Returns:
        Config: Parsed configuration object.
    """
    try:
        _service_config_str = os.getenv("ServiceConfig", "{}")
        _service_config = json.loads(_service_config_str)

        global _config_instance
        if _config_instance is not None:
            return _config_instance
        _config_instance = Config.model_validate(
            {
                "service_config": _service_config,
            }
        )
    except Exception as e:
        raise EnvironmentError(f"Fail to parse 'Config': {e}")

    return _config_instance


def get_embedding_config() -> EmbeddingServiceConfig | None:
    """Get Embedding Service configuration from global config."""
    gcfg = get_global_config()
    return gcfg.service_config.embedding


def get_rerank_config() -> RerankServiceConfig | None:
    """Get Rerank Service configuration from global config."""
    gcfg = get_global_config()
    return gcfg.service_config.rerank


def get_ontology_config() -> OntologyServiceConfig | None:
    """Get Ontology Service configuration from global config."""
    gcfg = get_global_config()
    return gcfg.service_config.ontology


def get_workspace_id() -> str | None:
    """Get Workspace ID from global config."""
    gcfg = get_global_config()
    return gcfg.service_config.workspaceId


def get_config(config_json: dict) -> Config:
    """Load and parse configuration from dict."""
    try:
        config = Config.model_validate(config_json)
    except Exception as e:
        raise EnvironmentError(f"Fail to parse 'Config': {e}")

    return config
