from pydantic_settings import BaseSettings
from pydantic import AnyHttpUrl, field_validator
from typing import List, Union, Optional
import secrets
import os

# Resolve .env relative to this file so it is always found regardless of
# the current working directory (e.g. when Passenger starts the app from /).
_ENV_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", ".env")


class Settings(BaseSettings):
    # App
    APP_NAME: str = "StemGenius Platform"
    APP_VERSION: str = "1.0.0"
    APP_ENV: str = "development"   # development | production
    DEBUG: bool = True

    # Security
    SECRET_KEY: str = secrets.token_urlsafe(64)
    ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    REFRESH_TOKEN_EXPIRE_DAYS: int = 7
    MAX_LOGIN_ATTEMPTS: int = 5
    ACCOUNT_LOCK_MINUTES: int = 30

    # Database
    DB_HOST: str = "localhost"
    DB_PORT: int = 3306
    DB_NAME: str = "stemgenius_db"
    DB_USER: str = "root"
    DB_PASSWORD: str = ""
    # Optional Unix socket path — used by some cPanel shared hosts
    # e.g. /var/lib/mysql/mysql.sock   Leave blank to use TCP host:port.
    DB_SOCKET: Optional[str] = None
    SQLITE_DB_PATH: str = "./stemgenius_offline.db"
    USE_SQLITE: bool = False

    # Public base URL of the backend — used to build absolute upload URLs
    # Dev default is empty (relative paths). Set to https://apx.stemgeniusltd.com in prod.
    API_BASE_URL: str = ""

    # Subscription
    SUBSCRIPTION_CHECK_INTERVAL_HOURS: int = 24
    PREMIUM_GRACE_PERIOD_DAYS: int = 3

    # CORS — comma-separated string OR JSON list in .env
    CORS_ORIGINS: Union[List[str], str] = [
        "http://localhost:5173",
        "http://localhost:3000",
        "http://127.0.0.1:5173",
        # "http://apx.stemgeniusltd.com",
        # "https://apx.stemgeniusltd.com",
        "http://gaming.stemgeniusltd.com",
        # "https://gaming.stemgeniusltd.com",
        # "http://apx.stemgeniusltd.com",
        # "https://apx.stemgeniusltd.com",
        #"https://trace-deceiver-cage.ngrok-free.dev"
    ]

    @field_validator("CORS_ORIGINS", mode="before")
    @classmethod
    def parse_cors(cls, v):
        if isinstance(v, str):
            # Support both comma-separated and JSON list strings
            v = v.strip()
            if v.startswith("["):
                import json
                return json.loads(v)
            return [i.strip() for i in v.split(",") if i.strip()]
        return v

    # Email
    SMTP_HOST: str = "smtp.gmail.com"
    SMTP_PORT: int = 587
    SMTP_USER: str = ""
    SMTP_PASSWORD: str = ""
    SMTP_FROM_NAME: str = "StemGenius"
    SMTP_TLS: bool = True

    # Cloudinary
    CLOUDINARY_CLOUD_NAME: str = ""
    CLOUDINARY_API_KEY: str = ""
    CLOUDINARY_API_SECRET: str = ""

    # Redis
    REDIS_URL: str = "redis://localhost:6379/0"

    # API
    API_PREFIX: str = "/api/v1"
    RATE_LIMIT_PER_MINUTE: int = 60

    @property
    def is_production(self) -> bool:
        return self.APP_ENV == "production"

    def _mysql_dsn(self, driver: str) -> str:
        """Build MySQL DSN supporting both TCP and Unix socket connections."""
        creds = f"{self.DB_USER}:{self.DB_PASSWORD}"
        db = f"{self.DB_NAME}?charset=utf8mb4"
        if self.DB_SOCKET:
            # Unix socket — common on cPanel shared hosts
            return f"mysql+{driver}://{creds}@/{db}&unix_socket={self.DB_SOCKET}"
        return f"mysql+{driver}://{creds}@{self.DB_HOST}:{self.DB_PORT}/{db}"

    @property
    def database_url(self) -> str:
        if self.USE_SQLITE:
            return f"sqlite+aiosqlite:///{self.SQLITE_DB_PATH}"
        return self._mysql_dsn("pymysql")

    @property
    def async_database_url(self) -> str:
        if self.USE_SQLITE:
            return f"sqlite+aiosqlite:///{self.SQLITE_DB_PATH}"
        return self._mysql_dsn("aiomysql")

    class Config:
        env_file = _ENV_FILE
        env_file_encoding = "utf-8"
        case_sensitive = True


settings = Settings()
