"""
CODH Core Middleware
Enterprise-grade security and installation middleware
"""

import json
import time
from django.http import JsonResponse
from django.conf import settings
from django.urls import resolve, Resolver404
from django.utils.deprecation import MiddlewareMixin
from .models import SystemConfiguration, AuditLog


class InstallationMiddleware(MiddlewareMixin):
    """
    Middleware to handle first-load setup wizard.
    Redirects all requests to setup if system is not configured.
    """
    
    EXEMPT_PATHS = [
        '/api/setup/',
        '/health/',
        '/static/',
        '/media/',
        '/admin/',
    ]
    
    def process_request(self, request):
        # Skip if not in installation mode
        if not settings.INSTALLATION_MODE:
            return None
            
        # Check exempt paths
        path = request.path
        for exempt in self.EXEMPT_PATHS:
            if path.startswith(exempt):
                return None
        
        # Check if system is configured
        try:
            config = SystemConfiguration.objects.first()
            if config and config.is_configured:
                return None
        except:
            pass
        
        # Allow setup API endpoints
        if path.startswith('/api/setup/'):
            return None
            
        # Return setup required response
        return JsonResponse({
            'status': 'setup_required',
            'message': 'System installation required. Please complete the setup wizard.',
            'redirect': '/setup',
            'installation_mode': True
        }, status=503)


class SecurityHeadersMiddleware(MiddlewareMixin):
    """
    Add security headers to all responses
    """
    
    def process_response(self, request, response):
        # Prevent clickjacking
        response['X-Frame-Options'] = 'DENY'
        
        # Prevent MIME type sniffing
        response['X-Content-Type-Options'] = 'nosniff'
        
        # XSS Protection
        response['X-XSS-Protection'] = '1; mode=block'
        
        # Referrer Policy
        response['Referrer-Policy'] = 'strict-origin-when-cross-origin'
        
        # Content Security Policy
        response['Content-Security-Policy'] = (
            "default-src 'self'; "
            "script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
            "style-src 'self' 'unsafe-inline'; "
            "img-src 'self' data: https:; "
            "font-src 'self' data:; "
            "connect-src 'self' https:;"
        )
        
        # Permissions Policy
        response['Permissions-Policy'] = (
            'accelerometer=(), camera=(), geolocation=(), gyroscope=(), '
            'magnetometer=(), microphone=(), payment=(), usb=()'
        )
        
        return response


class AuditLogMiddleware(MiddlewareMixin):
    """
    Log all API requests for audit trail
    """
    
    EXEMPT_PATHS = ['/health/', '/static/', '/media/']
    
    def process_request(self, request):
        request.start_time = time.time()
        return None
    
    def process_response(self, request, response):
        # Skip exempt paths
        path = request.path
        for exempt in self.EXEMPT_PATHS:
            if path.startswith(exempt):
                return response
        
        # Only log API requests
        if not path.startswith('/api/'):
            return response
        
        # Calculate request duration
        duration = getattr(request, 'start_time', None)
        if duration:
            duration = time.time() - duration
        
        # Get user info
        user = request.user if hasattr(request, 'user') and request.user.is_authenticated else None
        
        # Get client IP
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0].strip()
        else:
            ip = request.META.get('REMOTE_ADDR')
        
        # Log the request (async)
        try:
            AuditLog.objects.create(
                user=user,
                action=f"{request.method} {path}",
                ip_address=ip,
                user_agent=request.META.get('HTTP_USER_AGENT', '')[:255],
                request_data=self._get_request_data(request),
                response_status=response.status_code,
                duration=duration
            )
        except:
            pass
        
        return response
    
    def _get_request_data(self, request):
        """Safely extract request data"""
        try:
            if request.method in ['POST', 'PUT', 'PATCH']:
                if request.content_type == 'application/json':
                    return json.loads(request.body.decode('utf-8'))
                return dict(request.POST)
            return dict(request.GET)
        except:
            return {}


class RateLimitMiddleware(MiddlewareMixin):
    """
    Custom rate limiting middleware
    """
    
    def process_request(self, request):
        # Get client IP
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0].strip()
        else:
            ip = request.META.get('REMOTE_ADDR')
        
        # Check rate limit (simplified implementation)
        # In production, use Redis for distributed rate limiting
        return None
