"""
DRF Permissions for PX Source User access control.

Provides permission classes to restrict API access based on user role:
- Source users can only access their own data
- Admins have full access
"""
from rest_framework import permissions
from apps.px_sources.models import SourceUser


class IsSourceUser(permissions.BasePermission):
    """
    Allow access only to active source users.
    
    Use this on views that should ONLY be accessible to source users.
    
    Example:
        permission_classes = [IsSourceUser]
    """
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Check if user has source user profile
        if not hasattr(request.user, 'source_user_profile'):
            return False
        
        # Check if source user is active
        source_user = request.user.source_user_profile
        return source_user.is_active


class IsSourceUserOrAdmin(permissions.BasePermission):
    """
    Allow access to source users AND admins.
    
    Use this on views that should be accessible to:
    - Active source users
    - PX Admins, Hospital Admins, Department Managers
    
    Example:
        permission_classes = [IsSourceUserOrAdmin]
    """
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Allow admins
        if request.user.is_superuser or request.user.is_px_admin():
            return True
        
        # Allow hospital admins
        if request.user.is_hospital_admin():
            return True
        
        # Allow active source users
        if hasattr(request.user, 'source_user_profile'):
            source_user = request.user.source_user_profile
            return source_user.is_active
        
        return False


class IsSourceUserOwnData(permissions.BasePermission):
    """
    Object-level permission to ensure source users can only access their own data.
    
    Use this on detail views to ensure source users can only view/edit
    complaints and inquiries from their assigned source.
    
    Example:
        permission_classes = [IsSourceUserOrAdmin, IsSourceUserOwnData]
    """
    
    def has_object_permission(self, request, view, obj):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Admins can access everything
        if request.user.is_superuser or request.user.is_px_admin():
            return True
        
        # Check if user is a source user
        if not hasattr(request.user, 'source_user_profile'):
            return False
        
        source_user = request.user.source_user_profile
        
        if not source_user.is_active:
            return False
        
        # Check if object belongs to user's source
        if hasattr(obj, 'source'):
            return obj.source == source_user.source
        
        # If object doesn't have a source field, deny access
        return False


class IsAdminUser(permissions.BasePermission):
    """
    Allow access only to admin users (not source users).
    
    Use this on admin-only API endpoints.
    
    Example:
        permission_classes = [IsAdminUser]
    """
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Block pure source users
        if _is_pure_source_user(request.user):
            return False
        
        # Allow admins
        return request.user.is_superuser or request.user.is_px_admin() or request.user.is_hospital_admin()


class IsPXAdmin(permissions.BasePermission):
    """
    Allow access only to PX Admins.
    
    Use this on PX Admin-only API endpoints.
    """
    
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        return request.user.is_px_admin()


def _is_pure_source_user(user):
    """
    Check if user is ONLY a source user with no admin roles.
    """
    admin_groups = ['PX Admin', 'Hospital Admin', 'Department Manager']
    
    # Check if user has any admin roles
    has_admin_role = user.groups.filter(name__in=admin_groups).exists()
    
    if has_admin_role:
        return False
    
    # Check if user is a source user
    has_source_user_profile = hasattr(user, 'source_user_profile')
    
    if has_source_user_profile:
        source_user = user.source_user_profile
        if source_user.is_active:
            return True
    
    return False
