"""Pydantic Settings 定义。

每个 Settings 类对应 app.toml 中的一个 [SECTION]。
字段名 = SECTION_KEY（TOML 展平后的环境变量名）。
"""

from __future__ import annotations

from pydantic_settings import BaseSettings


class _Base(BaseSettings):
    """所有 Settings 的基类。"""
    model_config = {"env_file": None, "extra": "ignore"}


class AppSettings(_Base):
    """应用基础配置 [APP]。"""
    APP_NAME: str = "LeAudit Platform"
    APP_HOST: str = "0.0.0.0"
    APP_PORT: int = 8000
    APP_REGION: str = "default"
    APP_CORS_ORIGINS: str = "*"


class JwtSettings(_Base):
    """JWT 配置 [JWT]。"""
    JWT_SECRET_KEY: str = ""
    JWT_ACCESS_TOKEN_EXPIRE_HOURS: int = 24
    JWT_ALGORITHM: str = "HS256"


class DbSettings(_Base):
    """数据库配置 [DB]。"""
    DB_HOST: str = "localhost"
    DB_PORT: int = 5432
    DB_NAME: str = "leaudit"
    DB_USER: str = "postgres"
    DB_PASSWORD: str = ""

    @property
    def ASYNCPG_DATABASE_URL(self) -> str:
        """动态构建 asyncpg 连接 URL。"""
        return (
            f"postgresql+asyncpg://{self.DB_USER}:{self.DB_PASSWORD}"
            f"@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
        )


class RedisSettings(_Base):
    """Redis 配置 [REDIS]。"""
    REDIS_HOST: str = "localhost"
    REDIS_PORT: int = 6379
    REDIS_DB: int = 0
    REDIS_PASSWORD: str = ""
    REDIS_KEY_PREFIX: str = "leaudit"


class OssSettings(_Base):
    """OSS 对象存储配置 [OSS]。"""
    OSS_ENDPOINT: str = ""
    OSS_BASE_URL: str = ""
    OSS_ACCESS_KEY: str = ""
    OSS_SECRET_KEY: str = ""
    OSS_BUCKET: str = "leaudit"
    OSS_REGION: str = ""
    OSS_USE_SSL: bool = True
    OSS_PRESIGN_EXPIRE_SECONDS: int = 3600


class LlmSettings(_Base):
    """LLM 配置 [LLM]。"""
    LLM_BASE_URL: str = ""
    LLM_MODEL: str = ""
    LLM_API_KEY: str = ""


class VlmSettings(_Base):
    """VLM 配置 [VLM]。"""
    VLM_BASE_URL: str = ""
    VLM_MODEL: str = ""
    VLM_API_KEY: str = ""


class OcrSettings(_Base):
    """OCR 配置 [OCR]。"""
    OCR_BASE_URL: str = ""
    OCR_TIMEOUT: int = 300


class LeauditSettings(_Base):
    """LeAudit 引擎配置 [LEAUDIT]。"""
    LEAUDIT_RULES_DIR: str = "rules"
    LEAUDIT_RESCUE_MODE: str = "auto"
    LEAUDIT_LLM_MAX_CONCURRENCY: int = 5
    LEAUDIT_VLM_MAX_CONCURRENCY: int = 3
    LEAUDIT_LLM_REQUEST_TIMEOUT: int = 120
    LEAUDIT_LLM_RETRY_MAX_ATTEMPTS: int = 3
    LEAUDIT_LLM_RETRY_BACKOFF_BASE_SECONDS: float = 1.0
    LEAUDIT_VLM_REQUEST_TIMEOUT: int = 90
    LEAUDIT_VLM_RETRY_MAX_ATTEMPTS: int = 2
    LEAUDIT_VLM_RETRY_BACKOFF_BASE_SECONDS: float = 1.0
    LEAUDIT_OCR_VLM_CONCURRENCY: int = 3
    LEAUDIT_OCR_RETRY_MAX_ATTEMPTS: int = 3
    LEAUDIT_OCR_RETRY_BACKOFF_BASE_SECONDS: float = 1.0
    LEAUDIT_SIGNATURE_PROBE_CONCURRENCY: int = 2
    LEAUDIT_SIGNATURE_PROBE_TIMEOUT: int = 20
    LEAUDIT_SIGNATURE_PROBE_RETRY_MAX_ATTEMPTS: int = 2
    LEAUDIT_SIGNATURE_PROBE_RETRY_BACKOFF_BASE_SECONDS: float = 0.5
    LEAUDIT_WORKER_QUEUE_URGENT: str = "leaudit.urgent"
    LEAUDIT_WORKER_QUEUE_NORMAL: str = "leaudit.normal"
    LEAUDIT_WORKER_CONCURRENCY: int = 2
    LEAUDIT_RUN_LOCK_SECONDS: int = 1800
    LEAUDIT_STUCK_SCAN_CRON_MINUTES: int = 5
    LEAUDIT_STUCK_TIMEOUT_MINUTES: int = 20
    LEAUDIT_TASK_SOFT_TIME_LIMIT: int = 3300
    LEAUDIT_TASK_TIME_LIMIT: int = 3600


# 实例化所有 Settings
app = AppSettings()
jwt = JwtSettings()
db = DbSettings()
redis = RedisSettings()
oss = OssSettings()
llm = LlmSettings()
vlm = VlmSettings()
ocr = OcrSettings()
leaudit = LeauditSettings()
