from functools import wraps
from django.shortcuts import redirect
from django.contrib import messages
from django.http import JsonResponse


def admin_required(view_func):
    """
    Decorator to restrict access to admin users only
    """
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('users:login')
        
        if request.user.role != 'admin' and not request.user.is_superuser:
            messages.error(request, 'You do not have permission to access this page.')
            return redirect('dashboard')
        
        return view_func(request, *args, **kwargs)
    return wrapper


def staff_required(view_func):
    """
    Decorator to restrict access to staff members only (admin, team_leader, loan_officer, secretary, auditor)
    """
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('users:login')
        
        if request.user.role not in ['admin', 'team_leader', 'loan_officer', 'secretary', 'auditor']:
            messages.error(request, 'You do not have permission to access this page.')
            return redirect('dashboard')
        
        return view_func(request, *args, **kwargs)
    return wrapper


def portfolio_access_required(view_func):
    """
    Decorator to ensure staff members only see data related to their assigned borrowers
    """
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('users:login')
        
        # Admin and superuser have full access
        if request.user.role == 'admin' or request.user.is_superuser:
            return view_func(request, *args, **kwargs)
        
        # Staff members (team_leader, loan_officer, secretary, auditor) have portfolio-based access
        if request.user.role in ['team_leader', 'loan_officer', 'secretary', 'auditor']:
            return view_func(request, *args, **kwargs)
        
        # Borrowers and other roles don't have access
        messages.error(request, 'You do not have permission to access this page.')
        return redirect('dashboard')
    
    return wrapper


def module_access_required(module):
    """
    Decorator to check if user has access permission for a specific module
    """
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated:
                return redirect('users:login')
            
            # Check if user has access permission for the module
            if not request.user.has_permission(module, 'access'):
                messages.error(request, f'You do not have permission to access {module.replace("_", " ").title()}.')
                return redirect('dashboard')
            
            return view_func(request, *args, **kwargs)
        return wrapper
    return decorator


def api_admin_required(view_func):
    """
    API decorator to restrict access to admin users only
    """
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({'error': 'Authentication required'}, status=401)
        
        if request.user.role != 'admin' and not request.user.is_superuser:
            return JsonResponse({'error': 'Admin access required'}, status=403)
        
        return view_func(request, *args, **kwargs)
    return wrapper


def api_staff_required(view_func):
    """
    API decorator to restrict access to staff members only
    """
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({'error': 'Authentication required'}, status=401)
        
        if request.user.role not in ['admin', 'team_leader', 'loan_officer', 'secretary', 'auditor']:
            return JsonResponse({'error': 'Staff access required'}, status=403)
        
        return view_func(request, *args, **kwargs)
    return wrapper


def role_required(allowed_roles):
    """
    Decorator to restrict access to users with specific roles
    
    Args:
        allowed_roles: List of allowed roles (e.g., ['admin', 'team_leader'])
    """
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated:
                return redirect('users:login')
            
            if request.user.role not in allowed_roles and not request.user.is_superuser:
                messages.error(request, 'You do not have permission to access this page.')
                return redirect('dashboard')
            
            return view_func(request, *args, **kwargs)
        return wrapper
    return decorator