from django.shortcuts import redirect
from django.urls import reverse
from django.contrib import messages
from django.http import HttpResponseRedirect
from .models import Tenant, TenantUser
from . import router

class TenantMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # CRITICAL FIX: Reset to public schema at request start to prevent cross-request contamination
        router.set_tenant(None)
        
        # Skip middleware for admin URLs and static files
        if request.path.startswith('/admin/') or request.path.startswith('/static/') or request.path.startswith('/media/'):
            try:
                return self.get_response(request)
            finally:
                # Ensure schema reset even for excluded paths
                router.set_tenant(None)

        # Skip for landing pages and auth pages
        if (request.path.startswith('/landing/') or 
            request.path.startswith('/auth/') or 
            request.path == '/' or
            request.path.startswith('/system-admin/') or
            request.path.startswith('/system-admin/suspended/')):
            try:
                return self.get_response(request)
            finally:
                # Ensure schema reset even for excluded paths
                router.set_tenant(None)

        try:
            # Check if user is authenticated and has tenant access
            if request.user.is_authenticated:
                tenant_code = request.session.get('tenant_code')

                if tenant_code:
                    try:
                        tenant = Tenant.objects.get(tenant_code=tenant_code)

                        # Check if tenant is suspended
                        if tenant.status == 'suspended':
                            return HttpResponseRedirect(f'/system-admin/suspended/{tenant_code}/')

                        # Check if tenant is active
                        if not tenant.is_active:
                            messages.error(request, f'Tenant {tenant.name} trial has expired.')
                            return redirect('authapp:login')

                        # Add tenant to request for easy access
                        request.tenant = tenant
                        
                        # CRITICAL FIX: Switch to tenant-specific PostgreSQL schema
                        router.set_tenant(tenant)

                        # Check if user has access to this tenant
                        if not request.user.is_superuser:
                            try:
                                tenant_user = TenantUser.objects.get(
                                    tenant=tenant, 
                                    user=request.user, 
                                    is_active=True
                                )
                                
                                # Security check: Only enforce tenant prefix for usernames with actual tenant code prefix
                                if '_' in request.user.username:
                                    prefix = request.user.username.split('_', 1)[0]
                                    # Check if prefix is an actual tenant code in database
                                    if Tenant.objects.filter(tenant_code__iexact=prefix).exists():
                                        # Username has a real tenant prefix, verify it matches this tenant
                                        if prefix.lower() != tenant_code.lower():
                                            messages.error(request, 'Access violation detected. Please log in with correct credentials.')
                                            return redirect('authapp:login')
                                # For legacy usernames (no tenant format), rely on TenantUser membership check
                                
                                request.tenant_user = tenant_user
                            except TenantUser.DoesNotExist:
                                messages.error(request, 'You do not have access to this tenant.')
                                return redirect('authapp:login')

                    except Tenant.DoesNotExist:
                        messages.error(request, 'Invalid tenant code.')
                        return redirect('authapp:login')
                else:
                    # No tenant code in session, redirect to login
                    if not request.path.startswith('/auth/'):
                        return redirect('authapp:login')

            return self.get_response(request)
            
        finally:
            # CRITICAL FIX: Always reset to public schema after request processing
            router.set_tenant(None)