"""<<project_name>> 配置加载 (config loader).

读取顺序 / Load order (later overrides earlier):
  1. 字段默认值 / field defaults
  2. config.toml  ([server], [app], [log] 段)
  3. .env 文件 / .env file
  4. 系统环境变量 (SERVER__HOST, SERVER__PORT, APP__LOG_LEVEL ...)

即：环境变量 > .env > config.toml > 默认值。环境变量以 `__` 分层覆盖 config.toml。
i.e. env vars > .env > config.toml > defaults. Env vars override config.toml.

★ 普通用户无需修改本文件 ★ —— 改 host/port 请改 config.toml 或 .env。
You normally never edit this file — change host/port in config.toml or .env.
"""

from pathlib import Path

from pydantic import BaseModel
from pydantic_settings import (
    BaseSettings,
    PydanticBaseSettingsSource,
    SettingsConfigDict,
    TomlConfigSettingsSource,
)

BASE_DIR = Path(__file__).resolve().parent.parent
CONFIG_FILE = BASE_DIR / "config.toml"


class ServerConfig(BaseModel):
    """HTTP 监听配置 (listen settings)."""

    host: str = "<<default_host>>"
    port: int = <<default_port>>
    reload: bool = False


class AppConfig(BaseModel):
    """应用级配置 (application settings)."""

    title: str = "<<project_name>>"
    log_level: str = "info"


class LogConfig(BaseModel):
    """日志配置 (logging configuration)，对应 config.toml 的 [log] 段."""

    # 日志级别 / log level: debug / info / warning / error / critical
    level: str = "info"

    # 输出格式 / output format: "console" (彩色人类可读) 或 "json" (结构化)
    format: str = "json"

    # 日志目录 / log directory (留空 = 不写文件)
    directory: str = "logs"

    # 显式文件路径 / explicit file path (优先于 directory；留空 = directory + 默认名)
    file: str = ""

    # 是否同时输出到控制台 / also log to console
    log_in_console: bool = True

    # 是否附带 文件名/函数/行号 / include filename/func/lineno
    show_line: bool = False

    # 单文件最大体积 (MB) / max size per file before rotation
    max_size: int = 10

    # 保留的轮转文件数量 / number of rotated backups to keep
    max_backups: int = 10

    # 旧日志保留天数 / days to keep old log files (0 = 永久)
    max_age: int = 30

    # 轮转后是否 gzip 压缩 / gzip-compress rotated files
    compress: bool = True


class Settings(BaseSettings):
    """全局配置 (global settings). 环境变量以 `__` 分层覆盖 config.toml。"""

    model_config = SettingsConfigDict(
        env_file=".env",
        env_nested_delimiter="__",
        extra="ignore",
        toml_file=CONFIG_FILE,
    )

    server: ServerConfig = ServerConfig()
    app: AppConfig = AppConfig()
    log: LogConfig = LogConfig()

    @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, ...]:
        """优先级 (高→低) / priority (high→low): init > env > .env > config.toml > defaults."""
        return (
            init_settings,
            env_settings,
            dotenv_settings,
            TomlConfigSettingsSource(settings_cls),
            file_secret_settings,
        )


def load_settings() -> Settings:
    """从 config.toml + .env + 环境变量构建配置实例 (env 覆盖 toml)."""
    return Settings()


settings = load_settings()
