from rest_framework import permissions


class IsAdmin(permissions.BasePermission):
    """
    Permission to allow only admin users to access.
    """
    message = "Only admin users have access to this resource."
    
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_staff and request.user.is_superuser)


class IsAuthenticated(permissions.BasePermission):
    """
    Permission to allow only authenticated users to access.
    """
    message = "Authentication required to access this resource."
    
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)


class IsSelfUser(permissions.BasePermission):
    """
    Permission to allow users to access only their own data.
    Assumes the object/view has an 'owner' or 'user' attribute.
    """
    message = "You can only access your own data."
    
    def has_object_permission(self, request, view, obj):
        # Check if the object has a 'user' attribute
        if hasattr(obj, 'user'):
            return obj.user == request.user
        # Check if the object has an 'owner' attribute
        elif hasattr(obj, 'owner'):
            return obj.owner == request.user
        # For User objects themselves
        elif hasattr(obj, 'pk'):
            return obj.pk == request.user.pk
        return False


class IsAuthenticatedOrReadOnly(permissions.BasePermission):
    """
    Permission to allow authenticated users full access,
    but allow anonymous users read-only access.
    """
    message = "Authentication required for this action."
    
    def has_permission(self, request, view):
        # Read permissions are allowed to any access (GET, HEAD, OPTIONS)
        if request.method in permissions.SAFE_METHODS:
            return True
        # Write permissions are only allowed to authenticated users
        return bool(request.user and request.user.is_authenticated)


class IsAdminOrReadOnly(permissions.BasePermission):
    """
    Permission to allow only admins to write,
    but allow anyone to read.
    """
    message = "Only admin users can modify this resource."
    
    def has_permission(self, request, view):
        # Read permissions are allowed to any access (GET, HEAD, OPTIONS)
        if request.method in permissions.SAFE_METHODS:
            return True
        # Write permissions are only allowed to admin users
        return bool(request.user and request.user.is_staff and request.user.is_superuser)


class IsAdminOrSelfUser(permissions.BasePermission):
    """
    Permission to allow only admins and the user themselves to access.
    Useful for user profile endpoints.
    """
    message = "You can only access your own data or admin access is required."
    
    def has_object_permission(self, request, view, obj):
        # Admin users get full access
        if request.user and request.user.is_staff and request.user.is_superuser:
            return True
        # Users can access their own data
        if hasattr(obj, 'user'):
            return obj.user == request.user
        elif hasattr(obj, 'pk'):
            return obj.pk == request.user.pk
        return False


class IsEmployer(permissions.BasePermission):
    """
    Permission to allow only users with employer role.
    Assumes user has a profile with role field.
    """
    message = "Only employers have access to this resource."
    
    def has_permission(self, request, view):
        if not (request.user and request.user.is_authenticated):
            return False
        
        try:
            return request.user.profile.role == 'employer'
        except:
            return False


class IsCandidate(permissions.BasePermission):
    """
    Permission to allow only users with candidate role.
    Assumes user has a profile with role field.
    """
    message = "Only candidates have access to this resource."
    
    def has_permission(self, request, view):
        if not (request.user and request.user.is_authenticated):
            return False
        
        try:
            return request.user.profile.role == 'candidate'
        except:
            return False


class IsEmployerOrReadOnly(permissions.BasePermission):
    """
    Permission to allow employers to write,
    but allow anyone to read.
    """
    message = "Only employers can create or modify job postings."
    
    def has_permission(self, request, view):
        # Read permissions are allowed to any access
        if request.method in permissions.SAFE_METHODS:
            return True
        # Write permissions are only allowed to employers
        if not (request.user and request.user.is_authenticated):
            return False
        
        try:
            return request.user.profile.role == 'employer'
        except:
            return False
