from pathlib import Path

from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


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

    APP_NAME: str = "QingYun Cloud"
    APP_VERSION: str = "0.1.0"
    DEBUG: bool = False

    DB_HOST: str = "127.0.0.1"
    DB_PORT: int = 3306
    DB_USER: str = "root"
    DB_PASSWORD: str = ""
    DB_NAME: str = "qycw"

    REDIS_HOST: str = "127.0.0.1"
    REDIS_PORT: int = 6379
    REDIS_PASSWORD: str | None = None
    REDIS_DB: int = 10

    SMTP_HOST: str = ""
    SMTP_PORT: int = 465
    SMTP_USER: str = ""
    SMTP_PASSWORD: str = ""
    SMTP_FROM_EMAIL: str = ""
    SMTP_FROM_NAME: str = "QingYun Cloud"
    EMAIL_PROVIDER: str = "mode.email.aliyunemail.provider:create_provider"

    SMS_ACCESS_KEY_ID: str = ""
    SMS_ACCESS_KEY_SECRET: str = ""
    SMS_ENDPOINT: str = "dypnsapi.aliyuncs.com"
    SMS_SIGN_NAME: str = ""
    SMS_TEMPLATE_CODE: str = ""
    SMS_PROVIDER: str = "mode.sms.aliyunsms.provider:create_provider"

    # 百度智能云人脸核身
    BAIDU_FACE_API_KEY: str = ""
    BAIDU_FACE_SECRET_KEY: str = ""
    BAIDU_FACE_APP_ID: str = ""
    BAIDU_FACE_VERIFY_REQUIRED: bool = False  # 是否强制实名认证
    BAIDU_FACE_VERIFY_FOR_PURCHASE: bool = True  # 购买前是否需要实名
    BAIDU_FACE_VERIFY_FOR_RECHARGE: bool = True  # 充值前是否需要实名

    # Optional production command used by the admin plugin maintenance button.
    # Examples: "systemctl restart qycw-backend" or "supervisorctl restart qycw-backend".
    PLUGIN_RELOAD_COMMAND: str = ""

    GEETEST_CAPTCHA_ID: str = ""
    GEETEST_CAPTCHA_KEY: str = ""
    GEETEST_API_SERVER: str = "http://gcaptcha4.geetest.com"
    GEETEST_FAIL_OPEN: bool = False

    JWT_SECRET_KEY: str = "change-me-to-a-random-64-byte-string"
    JWT_ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    REFRESH_TOKEN_EXPIRE_DAYS: int = 7

    CORS_ORIGINS: list[str] = ["http://localhost:5173"]
    FRONTEND_URL: str = "http://localhost:5173"
    PUBLIC_BACKEND_URL: str = ""
    MEDIA_ROOT: str = "media"
    MEDIA_URL: str = "/media"
    TICKET_IMAGE_MAX_BYTES: int = 5 * 1024 * 1024

    # 易支付
    EPAY_PID: str = ""
    EPAY_KEY: str = ""
    EPAY_API_URL: str = ""          # 末尾不带斜杠，如 https://pay.ly-y.cn
    EPAY_NOTIFY_URL: str = ""       # 异步回调地址
    EPAY_RETURN_URL: str = ""       # 同步跳转地址（支付完成后跳回前端）
    EPAY_SITE_NAME: str = "清云互联"
    RECHARGE_MIN_YUAN: float = 0.1  # 最低充值金额（元）
    RECHARGE_MAX_YUAN: float = 1000.0  # 最高充值金额（元）

    @field_validator("DEBUG", mode="before")
    @classmethod
    def parse_debug(cls, value):
        if isinstance(value, bool):
            return value
        if isinstance(value, str):
            normalized = value.strip().lower()
            if normalized in {"release", "prod", "production"}:
                return False
            if normalized in {"debug", "dev", "development"}:
                return True
        return value

    @property
    def DATABASE_URL(self) -> str:
        return (
            f"mysql+aiomysql://{self.DB_USER}:{self.DB_PASSWORD}"
            f"@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
            f"?charset=utf8mb4"
        )

    @property
    def DATABASE_URL_SYNC(self) -> str:
        return (
            f"mysql+pymysql://{self.DB_USER}:{self.DB_PASSWORD}"
            f"@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
            f"?charset=utf8mb4"
        )

    @property
    def MEDIA_ROOT_PATH(self) -> Path:
        path = Path(self.MEDIA_ROOT)
        if path.is_absolute():
            return path
        return Path(__file__).resolve().parents[1] / path


settings = Settings()
