from __future__ import annotations

from functools import lru_cache
from pathlib import Path
from typing import Literal, Optional

from pydantic_settings import BaseSettings, SettingsConfigDict


def _guess_env_file(app_env: str) -> Optional[str]:
    """
    根据 APP_ENV 选择 env 文件。

    说明：
    - `.env.dev` / `.env.prod` 不进入仓库，通常由运维在部署时放到 `server/` 目录
    - 如果文件不存在，则返回 None，让系统从“真实环境变量”读取
    """

    base_dir = Path(__file__).resolve().parents[2]  # .../server/app -> .../server
    candidates = {
        "dev": base_dir / ".env.dev",
        "prod": base_dir / ".env.prod",
    }
    p = candidates.get(app_env)
    if p and p.exists():
        return str(p)
    return None


class Settings(BaseSettings):
    """
    应用配置（统一从环境变量读取）。

    注意：请不要把真实账号密码写入仓库；使用 `.env.dev/.env.prod` 或部署系统注入。
    """

    app_env: Literal["dev", "prod"] = "dev"
    app_name: str = "mindfulness-server"
    app_host: str = "0.0.0.0"
    app_port: int = 8000

    database_url: str

    redis_url: str
    celery_broker_url: str
    celery_result_backend: Optional[str] = None

    model_config = SettingsConfigDict(
        env_prefix="",
        case_sensitive=False,
        extra="ignore",
    )


@lru_cache
def get_settings() -> Settings:
    """
    获取配置（带缓存）。

    加载顺序：
    - 优先使用 `.env.dev/.env.prod`（若存在）
    - 否则使用系统环境变量
    """

    import os

    env = os.getenv("APP_ENV", "dev").strip() or "dev"
    env_file = _guess_env_file(env)

    return Settings(_env_file=env_file)

