import os
from datetime import timedelta
from dotenv import load_dotenv

basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '..', '.env'))

class Config:
    """Base configuration"""
    
    # Core Configuration
    # SECRET_KEY is critical for session security and CSRF protection
    # Never allow fallback values in production as they enable session hijacking
    SECRET_KEY = os.environ.get('SECRET_KEY')
    if not SECRET_KEY:
        raise ValueError("SECRET_KEY environment variable is required for security")
    

    # Feature flags
    FEATURES = {
        "gamification_leaderboards": True,
        "payments": True,  # Feature flag for payments - ENABLED FOR DEMO
    }
    # Database Configuration - Force Postgres in production
    basedir = os.path.abspath(os.path.dirname(__file__))
    
    # PRODUCTION DATABASE ENFORCEMENT - PostgreSQL only
    DATABASE_URL = os.environ.get('DATABASE_URL')
    
    if os.environ.get('FLY_APP_NAME'):  # Running on Fly.io
        if not DATABASE_URL:
            raise RuntimeError("DATABASE_URL must be set in production environment")
        if 'sqlite' in DATABASE_URL.lower():
            raise RuntimeError("SQLite is not allowed. Use PostgreSQL only.")
        # Handle postgres:// vs postgresql:// (Fly.io uses postgres://)
        if DATABASE_URL.startswith('postgres://'):
            DATABASE_URL = DATABASE_URL.replace('postgres://', 'postgresql://', 1)
        SQLALCHEMY_DATABASE_URI = DATABASE_URL
    else:
        # Development also uses PostgreSQL
        if not DATABASE_URL:
            # Default to local PostgreSQL if DATABASE_URL not set
            SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/rateright_dev'
        else:
            # Validate no SQLite in development either
            if 'sqlite' in DATABASE_URL.lower():
                raise RuntimeError("SQLite is not allowed. Use PostgreSQL only.")
            # Handle postgres:// vs postgresql:// for development too
            if DATABASE_URL.startswith('postgres://'):
                DATABASE_URL = DATABASE_URL.replace('postgres://', 'postgresql://', 1)
            SQLALCHEMY_DATABASE_URI = DATABASE_URL
    
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    
    # DATABASE CONNECTION POOLING CONFIGURATION
    # These settings prevent "server closed the connection unexpectedly" errors
    SQLALCHEMY_ENGINE_OPTIONS = {
        'pool_size': 10,  # Number of connections to maintain in pool
        'pool_recycle': 300,  # Recycle connections after 5 minutes
        'pool_pre_ping': True,  # Test connections before using them
        'pool_timeout': 30,  # Timeout for getting connection from pool
        'max_overflow': 20,  # Maximum overflow connections beyond pool_size
        'echo_pool': False,  # Set to True for connection pool debugging
        'connect_args': {
            'connect_timeout': 10,  # Connection timeout in seconds
            'options': '-c statement_timeout=30000'  # 30 second statement timeout
        }
    }
    
    # JWT Configuration
    JWT_SECRET_KEY = os.environ.get('JWT_SECRET_KEY') or SECRET_KEY
    JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1)
    JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30)
    
    # Security
    WTF_CSRF_ENABLED = True
    WTF_CSRF_TIME_LIMIT = None
    
    # Admin API Key for automated scripts
    ADMIN_API_KEY = os.environ.get('ADMIN_API_KEY')
    
    # File Upload
    MAX_CONTENT_LENGTH = 16 * 1024 * 1024  # 16MB max file size
    UPLOAD_FOLDER = os.path.join(basedir, '..', 'uploads')
    ALLOWED_EXTENSIONS = {'pdf', 'png', 'jpg', 'jpeg', 'gif', 'doc', 'docx'}
    
    # Email Configuration - Resend
    RESEND_API_KEY = os.environ.get('RESEND_API_KEY')
    MAIL_FROM_EMAIL = os.environ.get('MAIL_FROM_EMAIL', 'noreply@rateright.com.au')
    MAIL_FROM_NAME = os.environ.get('MAIL_FROM_NAME', 'RateRight')

    # SMS Configuration - Twilio
    # Using phone number directly for Australian mobile
    TWILIO_ACCOUNT_SID = os.environ.get('TWILIO_ACCOUNT_SID')
    TWILIO_AUTH_TOKEN = os.environ.get('TWILIO_AUTH_TOKEN')
    TWILIO_PHONE_NUMBER = os.environ.get('TWILIO_PHONE_NUMBER')
    
    # Base URL for email links (auto-detects from environment)
    if os.environ.get('FLY_APP_NAME'):
        # Production on Fly.io
        BASE_URL = os.environ.get('BASE_URL', 'https://rateright.com.au')
    else:
        # Local development
        BASE_URL = os.environ.get('BASE_URL', 'http://127.0.0.1:5001')
    
    # Pagination
    JOBS_PER_PAGE = 10
    WORKERS_PER_PAGE = 12
    
    # Cloudinary Configuration (for profile picture uploads)
    CLOUDINARY_CLOUD_NAME = os.environ.get('CLOUDINARY_CLOUD_NAME')
    CLOUDINARY_API_KEY = os.environ.get('CLOUDINARY_API_KEY')
    CLOUDINARY_API_SECRET = os.environ.get('CLOUDINARY_API_SECRET')
    
    # Stripe Payment Configuration (use dummy keys for demo mode)
    STRIPE_PUBLISHABLE_KEY = os.environ.get('STRIPE_PUBLISHABLE_KEY', 'pk_test_DEMO_MODE')
    STRIPE_SECRET_KEY = os.environ.get('STRIPE_SECRET_KEY', 'sk_test_DEMO_MODE')
    STRIPE_WEBHOOK_SECRET = os.environ.get('STRIPE_WEBHOOK_SECRET', 'whsec_DEMO_MODE')
    
    # TEST MODE: Set to False in production to enable real Stripe transfers
    # When True, simulates transfers without actually sending to Stripe Connect accounts
    STRIPE_TEST_MODE = os.environ.get('STRIPE_TEST_MODE', 'True').lower() == 'true'
    
    # Validate Stripe keys are present when payments feature is enabled (allow demo keys)
    if FEATURES.get('payments', False):
        if not STRIPE_PUBLISHABLE_KEY or STRIPE_PUBLISHABLE_KEY == '':
            raise ValueError("STRIPE_PUBLISHABLE_KEY environment variable is required when payments are enabled")
        if not STRIPE_SECRET_KEY or STRIPE_SECRET_KEY == '':
            raise ValueError("STRIPE_SECRET_KEY environment variable is required when payments are enabled")
        if not STRIPE_WEBHOOK_SECRET or STRIPE_WEBHOOK_SECRET == '':
            raise ValueError("STRIPE_WEBHOOK_SECRET environment variable is required when payments are enabled")

    # Admin API Configuration
    # Used for CLI/automation access to admin endpoints
    ADMIN_API_KEY = os.environ.get('ADMIN_API_KEY')
