from __future__ import annotations

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

LOCAL_ENVIRONMENTS = frozenset({"local", "development", "dev"})


class Settings(BaseSettings):
    """Runtime configuration for the Lucos cloud indexing service."""

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

    APP_NAME: str = "Lucos Cloud Client"
    ENVIRONMENT: str = Field(
        default="development",
        validation_alias=AliasChoices("ENVIRONMENT", "ENV"),
    )
    PORT: int = 6006
    LOG_LEVEL: str = "info"
    SERVICE_VERSION: str = "0.1.0"

    MONGO_URI: str = "mongodb://localhost:37017"
    DATABASE_NAME: str = "lucos_cloud_client"

    EMBEDDING_ENGINE_URL: str = "http://localhost:6004"
    EMBEDDING_ENGINE_TIMEOUT_SEC: int = 30
    GATEWAY_INTERNAL_SERVICE_SECRET: str = ""

    EMBED_BATCH_SIZE: int = 50

    MAX_CHUNKS_PER_REQUEST: int = 200
    MAX_CHUNK_CONTENT_BYTES: int = 65_536

    @field_validator("EMBEDDING_ENGINE_TIMEOUT_SEC", "MAX_CHUNKS_PER_REQUEST")
    @classmethod
    def _positive_int(cls, value: int) -> int:
        if value < 1:
            raise ValueError("must be >= 1")
        return value

    @field_validator("MAX_CHUNK_CONTENT_BYTES")
    @classmethod
    def _positive_chunk_bytes(cls, value: int) -> int:
        if value < 1024:
            raise ValueError("must be >= 1024")
        return value

    def resolved_environment(self) -> str:
        return (self.ENVIRONMENT or "development").strip().lower()

    def is_local(self) -> bool:
        return self.resolved_environment() in LOCAL_ENVIRONMENTS

    def validate_runtime(self) -> None:
        if self.is_local():
            return

        missing: list[str] = []
        for name, value in (
            ("MONGO_URI", self.MONGO_URI),
            ("EMBEDDING_ENGINE_URL", self.EMBEDDING_ENGINE_URL),
        ):
            if not str(value).strip():
                missing.append(name)

        if missing:
            raise ValueError(
                f"Missing required configuration: {', '.join(missing)}"
            )


settings = Settings()
