"""Shared configuration primitives."""

from pathlib import Path
from typing import Any, ClassVar, Tuple, Type

from pydantic import Field
from pydantic_settings import (
    BaseSettings,
    DotEnvSettingsSource,
    PydanticBaseSettingsSource,
    SettingsConfigDict,
    YamlConfigSettingsSource,
)


class BaseAppSettings(BaseSettings):
    """Base settings shared by all subsystems."""

    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
        populate_by_name=True,
        env_nested_delimiter="__",
    )

    app_env: str = Field(default="development", alias="APP_ENV")
    log_level: str = Field(default="INFO", alias="LOG_LEVEL")
    data_dir: Path = Field(default=Path("./data"), alias="DATA_DIR")
    chroma_persist_dir: Path = Field(default=Path(".chroma"), alias="CHROMA_PERSIST_DIR")

    # Subsystems can override this to scan for default config files
    default_config_files: ClassVar[Tuple[str, ...]] = ()

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: Type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> Tuple[PydanticBaseSettingsSource, ...]:
        """
        Customize settings sources to include optional config files.
        Priority: init_settings > config_file > env_settings > .env > secrets
        """
        config_file_path = init_settings.init_kwargs.get("config_file")

        # Scan for default config files if none provided explicitly
        if not config_file_path:
            for filename in cls.default_config_files:
                path = expand_home(filename)
                if path.exists():
                    config_file_path = path
                    break

        sources: list[PydanticBaseSettingsSource] = [init_settings]

        if config_file_path:
            path = Path(config_file_path)
            if path.suffix.lower() in (".yaml", ".yml"):
                sources.append(YamlConfigSettingsSource(settings_cls, yaml_file=path))
            else:
                # Default to properties/env style for others (.properties, .conf, etc)
                sources.append(DotEnvSettingsSource(settings_cls, env_file=path))

        sources.extend([env_settings, dotenv_settings, file_secret_settings])
        return tuple(sources)


def expand_home(path: str | Path) -> Path:
    """Expand a path containing user home shorthand."""
    return Path(path).expanduser().resolve()
