from __future__ import annotations

from pydantic import field_validator, model_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=[".env", "backend/.env"], env_file_encoding="utf-8")

    DATABASE_URL: str = "postgresql+asyncpg://scilit:scilit_dev@localhost:5432/scilit"
    DATABASE_URL_SYNC: str = "postgresql://scilit:scilit_dev@localhost:5432/scilit"
    REDIS_URL: str = "redis://localhost:6379"
    ES_URL: str = "http://localhost:9200"

    S3_ENDPOINT: str = "http://localhost:9000"
    S3_ACCESS_KEY: str = "minioadmin"
    S3_SECRET_KEY: str = "minioadmin"
    S3_BUCKET: str = "scilit-files"
    S3_REGION: str = "us-east-1"
    S3_SECURE: bool = False

    # ─── 腾讯云 COS（对象存储，替代 MinIO 用于生产） ───
    COS_SECRET_ID: str = ""
    COS_SECRET_KEY: str = ""
    COS_REGION: str = "ap-guangzhou"
    COS_BUCKET: str = "scilit-files"

    JWT_SECRET: str = "dev-secret-change-in-production"

    @field_validator("JWT_SECRET")
    @classmethod
    def warn_default_jwt(cls, v: str):
        if v == "dev-secret-change-in-production":
            import warnings
            warnings.warn("JWT_SECRET is still set to the default dev value! Change it in production.")
        return v

    @model_validator(mode="after")
    def check_production_jwt(self) -> "Settings":
        if not self.DEBUG:
            if self.JWT_SECRET == "dev-secret-change-in-production":
                raise ValueError("JWT_SECRET is still the insecure default! Set JWT_SECRET in .env")
            raw = self.JWT_SECRET.encode("utf-8")
            if len(raw) < 32:
                raise ValueError(f"JWT_SECRET 太短（{len(raw)} 字节），至少需要 32 字节")
            has_upper = any(c.isupper() for c in self.JWT_SECRET)
            has_lower = any(c.islower() for c in self.JWT_SECRET)
            has_digit = any(c.isdigit() for c in self.JWT_SECRET)
            has_special = any(not c.isalnum() for c in self.JWT_SECRET)
            if sum([has_upper, has_lower, has_digit, has_special]) < 3:
                raise ValueError("JWT_SECRET 需至少包含大写字母、小写字母、数字、特殊字符中的 3 种")
        return self

    JWT_ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 15
    REFRESH_TOKEN_EXPIRE_DAYS: int = 30

    SPECIALTY: str = "oncology"
    SPECIALTY_CONFIG_PATH: str = "config/specialties"

    DEBUG: bool = False
    TESTING: bool = False
    API_V1_PREFIX: str = "/api/v1"

    # AI 摘要 API（DeepSeek 兼容 OpenAI SDK）
    AI_API_KEY: str = ""
    AI_BASE_URL: str = "https://api.deepseek.com/v1"
    AI_MODEL: str = "deepseek-chat"

    # PubMed E-utilities API key（可选，注册后 10 req/s → 无 key 3 req/s）
    PUBMED_API_KEY: str = ""

    # 微信扫码登录（第一版已注释，待后续启用）
    # WECHAT_OAUTH_APP_ID: str = ""
    # WECHAT_OAUTH_APP_SECRET: str = ""

    # 微信支付（Native 扫码支付）
    WECHAT_APP_ID: str = ""
    WECHAT_MCH_ID: str = ""
    WECHAT_API_KEY: str = ""
    WECHAT_NOTIFY_URL: str = ""

    # SMS 短信（验证码发送）
    SMS_PROVIDER: str = ""
    SMS_ACCESS_KEY: str = ""
    SMS_SECRET_KEY: str = ""
    SMS_SIGN_NAME: str = ""
    SMS_TEMPLATE_CODE: str = ""

    # SMTP 邮件
    SMTP_HOST: str = ""
    SMTP_PORT: int = 587
    SMTP_USER: str = ""
    SMTP_PASSWORD: str = ""
    SMTP_FROM: str = ""

    # CORS: 生产环境改为具体域名列表
    CORS_ORIGINS: list[str] = ["http://localhost:5173", "http://localhost:3000", "http://127.0.0.1:5173"]

    # 公开访问基地址（SSO 回调、邮件链接等）
    PUBLIC_BASE_URL: str = "http://localhost:5173"

    # Stripe（可选）
    STRIPE_WEBHOOK_SECRET: str = ""

    # Sentry 监控（可选）
    SENTRY_DSN: str = ""


settings = Settings()
