"""Application configuration loaded from environment variables."""
from functools import lru_cache
from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
import secrets


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

    # Application
    APP_NAME: str = "BulkGmailMailer"
    ENVIRONMENT: str = "development"
    SECRET_KEY: str = "change-me-in-production"
    BASE_URL: str = "http://localhost:8000"
    FRONTEND_BASE_URL: str = "http://localhost:8000"

    # Database / Redis
    DATABASE_URL: str = "postgresql+psycopg://mailer:mailer_dev_pw@localhost:5432/bulkmailer"
    REDIS_URL: str = "redis://localhost:6379/0"
    CELERY_BROKER_DB: int = 1
    CELERY_RESULT_DB: int = 2

    # Security
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 12
    SESSION_COOKIE_NAME: str = "mailer_session"
    CSRF_COOKIE_NAME: str = "mailer_csrf"
    ENCRYPTION_KEY: str = ""  # Fernet key; auto-generated & persisted if empty
    PASSWORD_MIN_LENGTH: int = 10

    # Rate limiting
    RATE_LIMIT_PER_MINUTE: int = 240

    # Uploads
    MAX_UPLOAD_MB: int = 10
    UPLOAD_DIR: str = "uploads"
    ALLOWED_ATTACHMENT_EXTS: str = "pdf,html,htm,txt,png,jpg,jpeg"
    ALLOWED_TEMPLATE_EXTS: str = "html,htm,txt"

    # Recipients / campaign limits
    MAX_RECIPIENTS_PER_CAMPAIGN: int = 2000
    MAX_GMAIL_ACCOUNTS_PER_CAMPAIGN: int = 10
    MAX_SUBJECTS: int = 1000

    # Sending defaults (admin-configurable at runtime via ApplicationSettings table)
    DEFAULT_SEND_INTERVAL_SECONDS: float = 1.0
    DEFAULT_MAX_PER_ACCOUNT_PER_CAMPAIGN: int = 200
    DEFAULT_RETRIES: int = 3
    DEFAULT_RETRY_DELAY_SECONDS: int = 60
    MAX_ATTACHMENT_TOTAL_MB: int = 25
    MAX_ATTACHMENT_PER_FILE_MB: float = 15.0

    # Amount ranges (defaults; admin-configurable)
    AMOUNT_MIN: float = 300.0
    AMOUNT_MAX: float = 1500.0
    SHIPPING_MIN: float = 5.0
    SHIPPING_MAX: float = 50.0

    # Invoice number format tokens:
    #   {prefix}  literal prefix e.g. INV-
    #   {r}       lowercase alphanumeric random block
    #   {R}       uppercase alphanumeric random block
    #   {d}       decimal digits only
    #   {seq4}    4-digit campaign-scoped sequence
    #   {date}    YYYYMMDD
    INVOICE_NUMBER_FORMAT: str = "{prefix}{R4}-{R5}-{R6}-{seq4}"
    INVOICE_PREFIX: str = "INV-"

    # Unsubscribe
    UNSUBSCRIBE_BASE: str = ""  # defaults to BASE_URL

    # Test-mode integration test (real Gmail send) gate
    GMAIL_TEST_ACCOUNT_EMAIL: str = ""
    GMAIL_TEST_ACCOUNT_REFRESH_TOKEN: str = ""
    GMAIL_TEST_ACCOUNT_CLIENT_ID: str = ""
    GMAIL_TEST_ACCOUNT_CLIENT_SECRET: str = ""

    # OAuth client config import default file (optional)
    GOOGLE_OAUTH_CLIENT_JSON_PATH: str = ""

    @field_validator("ENCRYPTION_KEY", mode="after")
    @classmethod
    def _enc(cls, v: str) -> str:
        return v or ""


@lru_cache
def get_settings() -> Settings:
    return Settings()


settings = get_settings()
