"""
app/core/config.py — 环境变量加载 + 启动校验
必填项缺失则启动失败，不静默。
"""

import os
from functools import lru_cache

from pydantic import field_validator
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    # ── 必填（缺失启动保护）───────────────────────────
    FERNET_KEY: str
    JWT_SECRET: str
    DATABASE_URL: str
    MONGO_URI: str
    REDIS_URL: str

    # ── AI 提供商（不写死默认，可配置）──────────────────
    IMAGE_PROVIDER_PRIMARY: str = "gpt"
    IMAGE_PROVIDER_FALLBACK: str = "gemini"
    IMAGE_API_BASE: str = ""
    IMAGE_MODEL: str = "gpt-image-2"
    MODEL_IMAGE: str = "gpt-image-2"    # 别名，与 IMAGE_MODEL 同义
    MODEL_TEXT: str = "claude-opus-4-8"
    MODEL_VISION: str = ""              # 视觉模型（verify_real_image 脚本用）
    CLAUDE_API_URL: str = ""
    GEMINI_API_URL: str = ""

    # ── 多 Provider Key（各人自录，测试/真实出图脚本用）──
    APIPORTS_BASE_URL: str = ""
    APIPORTS_KEY: str = ""
    CODEPROXY_BASE_URL: str = ""
    CODEPROXY_KEY: str = ""

    # ── 应用配置 ──────────────────────────────────────
    APP_ENV: str = "development"
    JWT_EXPIRE_MINUTES: int = 60 * 24 * 7   # 7天
    CELERY_BROKER_URL: str = ""
    CELERY_RESULT_BACKEND: str = ""

    # ── 并发限制（可配置，不写死）─────────────────────
    MAX_CONCURRENT_TASKS_PER_USER: int = 2

    # ── 文件存储路径 ──────────────────────────────────
    UPLOAD_BASE_PATH: str = "uploads/packages"
    # StaticFiles 实际服务的绝对目录（与 main.py app.mount("/uploads", .../uploads) 一致）。
    # 容器内 main.py 在 /app/main.py，故 uploads 绝对根 = /app/uploads。
    # 所有写盘/读盘统一锚定此根，避免 api(cwd=/app) 与 worker(cwd=/) 相对路径解析不一致。
    UPLOAD_ABS_ROOT: str = "/app/uploads"

    model_config = {"env_file": ".env", "case_sensitive": True, "extra": "ignore"}

    @field_validator("FERNET_KEY")
    @classmethod
    def fernet_key_not_empty(cls, v: str) -> str:
        if not v or len(v) < 32:
            raise ValueError("FERNET_KEY must be set and at least 32 chars")
        return v

    @field_validator("JWT_SECRET")
    @classmethod
    def jwt_secret_not_empty(cls, v: str) -> str:
        if not v or len(v) < 32:
            raise ValueError("JWT_SECRET must be at least 32 characters")
        return v

    def celery_broker(self) -> str:
        return self.CELERY_BROKER_URL or self.REDIS_URL

    def celery_backend(self) -> str:
        return self.CELERY_RESULT_BACKEND or self.REDIS_URL


@lru_cache()
def get_settings() -> Settings:
    """单例配置，启动时校验一次。"""
    return Settings()
