"""
Smooth Schedule - Multi-Tenancy Settings Override
This file extends base.py and adds django-tenants configuration
"""

from .base import *  # noqa
from .base import INSTALLED_APPS, MIDDLEWARE, DATABASES, LOGGING, env

# =============================================================================
# MULTI-TENANCY CONFIGURATION (django-tenants)
# =============================================================================

# Shared apps - Available to all tenants (stored in 'public' schema)
SHARED_APPS = [
    'django_tenants',  # Must be first

    # Identity Domain (shared)
    'smoothschedule.identity.core',  # Core models (Tenant, Domain, PermissionGrant)
    'smoothschedule.identity.users',  # Users app (shared across tenants)

    # Platform Domain (shared)
    'smoothschedule.platform.admin',  # Platform management (TenantInvitation, etc.)
    'smoothschedule.platform.api',  # Public API v1 for third-party integrations
    'smoothschedule.platform.tenant_sites', # Site builder and custom domains

    # Django built-ins (must be in shared)
    'django.contrib.contenttypes',
    'django.contrib.auth',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',

    # Third-party apps that should be shared
    'rest_framework',
    'rest_framework.authtoken',
    'corsheaders',
    'drf_spectacular',
    'channels',  # WebSockets
    'allauth',
    'allauth.account',
    'allauth.mfa',
    'allauth.socialaccount',
    'django_celery_beat',
    'hijack',
    'hijack.contrib.admin',
    'crispy_forms',
    'crispy_bootstrap5',
    'csp',
    'djstripe',  # Stripe integration

    # Commerce Domain (shared for platform support)
    'smoothschedule.billing',  # Billing, subscriptions, entitlements
    'smoothschedule.commerce.tickets',  # Ticket system - shared for platform support access

    # Communication Domain (shared)
    'smoothschedule.communication.notifications',  # Notification system - shared for platform
    'smoothschedule.communication.credits',  # Communication credits (SMS/calling) - shared for billing
    'smoothschedule.communication.mobile',  # Field employee mobile app - shared for location tracking
]

# Tenant-specific apps - Each tenant gets isolated data in their own schema
TENANT_APPS = [
    'django.contrib.contenttypes',  # Needed for tenant schemas

    # Scheduling Domain (tenant-isolated)
    'smoothschedule.scheduling.schedule',  # Resource scheduling with configurable concurrency
    'smoothschedule.scheduling.automations',  # Automation system for scheduled tasks
    'smoothschedule.scheduling.contracts',  # Contract/e-signature system

    # Communication Domain (tenant-isolated)
    'smoothschedule.communication.messaging',  # Broadcast messaging system

    # Commerce Domain (tenant-isolated)
    'smoothschedule.commerce.payments',  # Stripe Connect payments bridge
]


# Override INSTALLED_APPS to include all unique apps
INSTALLED_APPS = list(dict.fromkeys(SHARED_APPS + TENANT_APPS))

# Tenant model configuration
TENANT_MODEL = "core.Tenant"
TENANT_DOMAIN_MODEL = "core.Domain"
PUBLIC_SCHEMA_NAME = 'public'

# =============================================================================
# DATABASE CONFIGURATION (Multi-schema)
# =============================================================================

# Override database engine for django-tenants
DATABASES['default']['ENGINE'] ='django_tenants.postgresql_backend'

# Database routers for tenant isolation
DATABASE_ROUTERS = [
    'django_tenants.routers.TenantSyncRouter',
]

# =============================================================================
# MIDDLEWARE CONFIGURATION
# =============================================================================
# CRITICAL: Order matters!

MIDDLEWARE = [
    # 0. CORS must be first to set headers before tenant resolution
    'corsheaders.middleware.CorsMiddleware',

    # 1. Tenant resolution
    'django_tenants.middleware.main.TenantMainMiddleware',
    'smoothschedule.identity.core.middleware.TenantHeaderMiddleware', # Support tenant switching via header

    # 2. Security middleware
    'django.middleware.security.SecurityMiddleware',
    'csp.middleware.CSPMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',

    # 3. Session & CSRF
    'django.contrib.sessions.middleware.SessionMiddleware',

    # 4. Sandbox mode - switches to sandbox schema if requested
    # MUST come after TenantMainMiddleware and SessionMiddleware
    'smoothschedule.identity.core.middleware.SandboxModeMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    
    # 4. Authentication
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    
    # 5. Hijack (Masquerading) - MUST come before our audit middleware
    'hijack.middleware.HijackUserMiddleware',
    
    # 6. MASQUERADE AUDIT - MUST come AFTER HijackUserMiddleware
    'smoothschedule.identity.core.middleware.MasqueradeAuditMiddleware',
    
    # 7. Messages, Clickjacking, and Allauth
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'allauth.account.middleware.AccountMiddleware',
]

# =============================================================================
# TEMPLATE CONTEXT PROCESSORS (for admin)
# =============================================================================

# Ensure required context processors are present
from .base import TEMPLATES  # noqa
if TEMPLATES and len(TEMPLATES) > 0:
    context_processors = TEMPLATES[0]['OPTIONS']['context_processors']
    if 'django.contrib.auth.context_processors.auth' not in context_processors:
        context_processors.insert(0, 'django.contrib.auth.context_processors.auth')
    if 'django.contrib.messages.context_processors.messages' not in context_processors:
        context_processors.append('django.contrib.messages.context_processors.messages')

# =============================================================================
# PASSWORD VALIDATION
# =============================================================================

# Password hashers
PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.Argon2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]

# Password validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 10,
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# =============================================================================
# HIJACK (MASQUERADING) CONFIGURATION
# =============================================================================

HIJACK_AUTHORIZATION_CHECK = 'smoothschedule.identity.core.permissions.can_hijack'
HIJACK_DISPLAY_ADMIN_BUTTON = True
HIJACK_USE_BOOTSTRAP = True
HIJACK_ALLOW_GET_REQUESTS = False  # Security: require POST
HIJACK_INSERT_BEFORE = True

# =============================================================================
# ENHANCED LOGGING FOR SECURITY AUDIT
# =============================================================================

# Extend existing logging configuration
LOGGING['formatters']['json'] = {
    '()': 'django.utils.log.ServerFormatter',
    'format': '[{server_time}] {message}',
    'style': '{',
}

LOGGING['handlers']['security_file'] = {
    'class': 'logging.handlers.RotatingFileHandler',
    'filename': str(BASE_DIR / 'logs' / 'security.log'),
    'maxBytes': 1024 * 1024 * 10,  # 10 MB
    'backupCount': 5,
    'formatter': 'json',
}

LOGGING['handlers']['masquerade_file'] = {
    'class': 'logging.handlers.RotatingFileHandler',
    'filename': str(BASE_DIR / 'logs' / 'masquerade.log'),
    'maxBytes': 1024 * 1024 * 10,  # 10 MB
    'backupCount': 5,
    'formatter': 'json',
}

# Ensure 'loggers' key exists in LOGGING
if 'loggers' not in LOGGING:
    LOGGING['loggers'] = {}

LOGGING['loggers']['smoothschedule.security'] = {
    'handlers': ['console', 'security_file'],
    'level': 'INFO',
    'propagate': False,
}

LOGGING['loggers']['smoothschedule.security.masquerade'] = {
    'handlers': ['console', 'masquerade_file'],
    'level': 'INFO',
    'propagate': False,
}

# Create logs directory if it doesn't exist
import os
os.makedirs(BASE_DIR / 'logs', exist_ok=True)

# =============================================================================
# CONTENT SECURITY POLICY (CSP)
# =============================================================================
# https://django-csp.readthedocs.io/en/latest/configuration.html

CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = (
    "'self'",
    "https://js.stripe.com",
    "https://connect-js.stripe.com",
    "https://www.googletagmanager.com",
    "https://www.google-analytics.com",
    "https://cdn.jsdelivr.net",  # Required for Swagger UI
    "blob:",  # Required for Stripe
)
CSP_STYLE_SRC = (
    "'self'",
    "'unsafe-inline'",  # Required for Stripe and many UI libraries
    "https://cdn.jsdelivr.net",  # Required for Swagger UI
)
CSP_IMG_SRC = (
    "'self'",
    "data:",
    "https://*.stripe.com",
    "https://www.google-analytics.com",
    "https://cdn.jsdelivr.net",  # Required for Swagger UI
)
CSP_CONNECT_SRC = (
    "'self'",
    "https://api.stripe.com",
    "https://www.google-analytics.com",
    "https://stats.g.doubleclick.net",
)
CSP_FRAME_SRC = (
    "'self'",
    "https://js.stripe.com",
    "https://hooks.stripe.com",
    "https://connect-js.stripe.com",
)
