# app/core/config.py
"""
Application configuration using Pydantic Settings.

This module provides classes and functions for:
- Configuration management via environment variables
- Database settings
- JWT and authentication configuration
- Main domain and multi-tenancy settings
- Admin initialization settings

Note: Environment detection is handled by app.core.environment module.
This module focuses purely on configuration storage and validation.
"""

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    """
    Settings class for application configuration.

    Environment detection is delegated to app.core.environment.
    This class focuses on configuration values only.
    """

    # =============================================================================
    # PROJECT INFORMATION
    # =============================================================================
    project_name: str = "Orion - Multi-Store Marketplace Platform"
    version: str = "2.2.0"

    # Clean description without HTML
    description: str = """
    Marketplace product import and management system with multi-store support.

    **Features:**
    - JWT Authentication with role-based access
    - Multi-marketplace product import (CSV processing)
    - Inventory management across multiple locations
    - Store management with individual configurations

    **Documentation:** Visit /documentation for complete guides
    **API Testing:** Use /docs for interactive API exploration
    """

    # =============================================================================
    # DATABASE (PostgreSQL only)
    # =============================================================================
    database_url: str = "postgresql://orion_user:secure_password@localhost:5432/orion_db"

    # =============================================================================
    # ADMIN INITIALIZATION (for init_production.py)
    # =============================================================================
    admin_email: str = "admin@orion.lu"
    admin_username: str = "admin"
    admin_password: str = "admin123"  # CHANGE IN PRODUCTION!
    admin_first_name: str = "Platform"
    admin_last_name: str = "Administrator"

    # =============================================================================
    # JWT AUTHENTICATION
    # =============================================================================
    jwt_secret_key: str = "change-this-in-production"
    jwt_expire_hours: int = 24
    jwt_expire_minutes: int = 30

    # =============================================================================
    # API SERVER
    # =============================================================================
    api_host: str = "0.0.0.0"
    api_port: int = 8000
    debug: bool = True

    # =============================================================================
    # DOCUMENTATION
    # =============================================================================
    documentation_url: str = "http://localhost:8001"

    # =============================================================================
    # MIDDLEWARE & SECURITY
    # =============================================================================
    allowed_hosts: list[str] = ["*"]  # Configure for production

    # Rate Limiting
    rate_limit_enabled: bool = True
    rate_limit_requests: int = 100
    rate_limit_window: int = 3600

    # =============================================================================
    # LOGGING
    # =============================================================================
    log_level: str = "INFO"
    log_file: str | None = None

    # =============================================================================
    # MAIN DOMAIN CONFIGURATION
    # =============================================================================
    main_domain: str = "wizard.lu"

    # Full base URL for outbound links (emails, redirects, etc.)
    # Must include protocol and port if non-standard.
    # Examples: http://localhost:8000, http://acme.localhost:9999, https://wizard.lu
    app_base_url: str = "http://localhost:8000"

    # Custom domain features
    allow_custom_domains: bool = True
    require_domain_verification: bool = True

    # SSL/TLS configuration for custom domains
    ssl_provider: str = "letsencrypt"  # or "cloudflare", "manual"
    auto_provision_ssl: bool = False

    # DNS verification
    dns_verification_prefix: str = "_orion-verify"
    dns_verification_ttl: int = 3600

    # =============================================================================
    # PLATFORM LIMITS
    # =============================================================================
    max_stores_per_user: int = 5
    max_team_members_per_store: int = 50
    invitation_expiry_days: int = 7

    # =============================================================================
    # STRIPE BILLING
    # =============================================================================
    stripe_secret_key: str = ""
    stripe_publishable_key: str = ""
    stripe_webhook_secret: str = ""
    stripe_trial_days: int = 30  # 1-month free trial (card collected upfront but not charged)

    # =============================================================================
    # EMAIL CONFIGURATION
    # =============================================================================
    # Provider: smtp, sendgrid, mailgun, ses
    email_provider: str = "smtp"
    email_from_address: str = "noreply@orion.lu"
    email_from_name: str = "Orion"
    email_reply_to: str = ""  # Optional reply-to address

    # SMTP Settings (used when email_provider=smtp)
    smtp_host: str = "localhost"
    smtp_port: int = 587
    smtp_user: str = ""
    smtp_password: str = ""
    smtp_use_tls: bool = True
    smtp_use_ssl: bool = False  # For port 465

    # SendGrid (used when email_provider=sendgrid)
    sendgrid_api_key: str = ""

    # Mailgun (used when email_provider=mailgun)
    mailgun_api_key: str = ""
    mailgun_domain: str = ""

    # Amazon SES (used when email_provider=ses)
    aws_access_key_id: str = ""
    aws_secret_access_key: str = ""
    aws_region: str = "eu-west-1"

    # Email behavior
    email_enabled: bool = True  # Set to False to disable all emails
    email_debug: bool = False  # Log emails instead of sending (for development)

    # =============================================================================
    # STOREFRONT DEFAULTS
    # =============================================================================
    # These can be overridden by AdminSetting in the database
    default_storefront_locale: str = "fr-LU"  # Currency/number formatting locale
    default_currency: str = "EUR"  # Default currency code

    # =============================================================================
    # DEMO/SEED DATA CONFIGURATION
    # =============================================================================
    # Controls for demo data seeding
    seed_demo_stores: int = 3  # Number of demo stores to create
    seed_customers_per_store: int = 15  # Customers per store
    seed_products_per_store: int = 20  # Products per store
    seed_orders_per_store: int = 10  # Orders per store

    # =============================================================================
    # CELERY / REDIS TASK QUEUE
    # =============================================================================
    # Redis URL for Celery broker and result backend
    redis_url: str = "redis://localhost:6379/0"

    # Feature flag: enable Celery for background tasks (False = use FastAPI BackgroundTasks)
    use_celery: bool = False

    # Flower monitoring dashboard
    flower_url: str = "http://localhost:5555"
    flower_password: str = "changeme"  # CHANGE IN PRODUCTION!

    # =============================================================================
    # SENTRY ERROR TRACKING
    # =============================================================================
    sentry_dsn: str | None = None  # Set to enable Sentry
    sentry_environment: str = "development"  # development, staging, production
    sentry_traces_sample_rate: float = 0.1  # 10% of transactions for performance monitoring

    # =============================================================================
    # MONITORING
    # =============================================================================
    enable_metrics: bool = False
    grafana_url: str = "https://grafana.wizard.lu"
    grafana_admin_user: str = "admin"
    grafana_admin_password: str = ""

    # =============================================================================
    # CLOUDFLARE R2 STORAGE
    # =============================================================================
    storage_backend: str = "local"  # "local" or "r2"
    r2_account_id: str | None = None
    r2_access_key_id: str | None = None
    r2_secret_access_key: str | None = None
    r2_bucket_name: str = "orion-media"
    r2_public_url: str | None = None  # Custom domain for public access (e.g., https://media.yoursite.com)

    # =============================================================================
    # CLOUDFLARE CDN / PROXY
    # =============================================================================
    cloudflare_enabled: bool = False  # Set to True when using CloudFlare proxy

    # =============================================================================
    # APPLE WALLET (LOYALTY MODULE)
    # =============================================================================
    loyalty_apple_pass_type_id: str | None = None
    loyalty_apple_team_id: str | None = None
    loyalty_apple_wwdr_cert_path: str | None = None
    loyalty_apple_signer_cert_path: str | None = None
    loyalty_apple_signer_key_path: str | None = None

    model_config = {"env_file": ".env", "extra": "ignore"}


# Singleton settings instance
settings = Settings()

# =============================================================================
# ENVIRONMENT UTILITIES - Module-level functions
# =============================================================================
# Import environment detection utilities
from app.core.environment import (
    get_environment,
    is_development,
    is_production,
    is_staging,
    should_use_secure_cookies,
)


def get_current_environment() -> str:
    """
    Get current environment.

    Convenience function that delegates to app.core.environment.
    Use this when you need just the environment string.
    """
    return get_environment()


def is_production_environment() -> bool:
    """
    Check if running in production.

    Convenience function that delegates to app.core.environment.
    Use this for production-specific logic.
    """
    return is_production()


def is_development_environment() -> bool:
    """
    Check if running in development.

    Convenience function that delegates to app.core.environment.
    Use this for development-specific logic.
    """
    return is_development()


def is_staging_environment() -> bool:
    """
    Check if running in staging.

    Convenience function that delegates to app.core.environment.
    Use this for staging-specific logic.
    """
    return is_staging()


# =============================================================================
# VALIDATION FUNCTIONS
# =============================================================================


def validate_database_url() -> None:
    """
    Validate that database URL is PostgreSQL.

    Raises:
        ValueError: If database URL is not PostgreSQL
    """
    if settings.database_url.startswith("sqlite"):
        raise ValueError(
            "SQLite is not supported. Please use PostgreSQL.\n"
            "Set DATABASE_URL environment variable to a PostgreSQL connection string.\n"
            "Example: postgresql://user:password@localhost:5432/dbname\n"
            "For local development, run: docker-compose up -d db"
        )
    if not settings.database_url.startswith("postgresql"):
        raise ValueError(
            f"Unsupported database: {settings.database_url.split(':')[0]}\n"
            "Only PostgreSQL is supported."
        )


def validate_production_settings() -> list[str]:
    """
    Validate settings for production environment.

    Returns:
        List of warning messages if configuration is insecure
    """
    warnings = []

    if is_production():
        # Check for default/insecure values
        if settings.admin_password == "admin123":
            warnings.append("⚠️  Using default admin password in production!")

        if settings.jwt_secret_key == "change-this-in-production":
            warnings.append("⚠️  Using default JWT secret key in production!")

        if settings.debug:
            warnings.append("⚠️  Debug mode enabled in production!")

        if "*" in settings.allowed_hosts:
            warnings.append("⚠️  ALLOWED_HOSTS is set to wildcard (*) in production!")

    return warnings


def print_environment_info():
    """Print current environment configuration."""
    print("\n" + "=" * 70)
    print(f"  ENVIRONMENT: {get_environment().upper()}")
    print("=" * 70)
    print(f"  Database:     {settings.database_url}")
    print(f"  Debug mode:   {settings.debug}")
    print(f"  API port:     {settings.api_port}")
    print(f"  Platform:     {settings.main_domain}")
    print(f"  Secure cookies: {should_use_secure_cookies()}")
    print("=" * 70 + "\n")

    # Show warnings if in production
    if is_production():
        warnings = validate_production_settings()
        if warnings:
            print("\n⚠️  PRODUCTION WARNINGS:")
            for warning in warnings:
                print(f"  {warning}")
            print()


# =============================================================================
# PUBLIC API
# =============================================================================
__all__ = [
    # Settings singleton
    "settings",
    # Environment detection (re-exported from app.core.environment)
    "get_environment",
    "is_development",
    "is_production",
    "is_staging",
    "should_use_secure_cookies",
    # Convenience functions
    "get_current_environment",
    "is_production_environment",
    "is_development_environment",
    "is_staging_environment",
    # Validation
    "validate_database_url",
    "validate_production_settings",
    "print_environment_info",
]
