from functools import wraps
from django.core.exceptions import PermissionDenied
from . import models
from django.db.models import Q
# import logging

# logger = logging.getLogger(__name__)


# class CustomPermissionRequiredMixin:
#     resource = None
#     action = None

#     def has_custom_permission(self, user, resource, action):
#         if not self.resource or not self.action:
#             raise AttributeError("Resource and action attributes must be defined in the view")

#         # if not request.user.is_authenticated:
#         #     return self.handle_no_permission()

#         if user.is_superuser:  # will chagne to principal type for admin
#             return True

#         permission_query = Q(
#             principal_group__role__app_resource_action__app_resource__name=resource,
#             principal_group__role__app_resource_action__app_action__name=action
#         )
#         return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists()

#     def dispatch(self, request, *args, **kwargs):
#         if not self.has_custom_permission(request.user, self.resource, self.action):
#             # logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}")
#             raise PermissionDenied("You do not have permission to access this resource.")
#         return super().dispatch(request, *args, **kwargs)

#     @classmethod
#     def as_decorator(cls, resource, action):
#         def decorator(view_func):
#             @wraps(view_func)
#             def _wrapped_view(request, *args, **kwargs):
#                 instance = cls()
#                 instance.resource = resource
#                 instance.action = action
#                 if not instance.has_custom_permission(request.user, instance.resource, instance.action):
#                     raise PermissionDenied("You do not have permission to access this resource.")
#                 return view_func(request, *args, **kwargs)
#             return _wrapped_view
#         return decorator


class ResourcePermissionRequiredMixin:
    resource = None

    def has_resource_permission(self, user, resource):
        # if not self.resource or resource:
        #     raise AttributeError("Resource attributes must be defined in the view")

        # if not request.user.is_authenticated:
        #     return self.handle_no_permission()

        if user.is_superuser:  # will chagne to principal type for admin
            return True

        permission_query = Q(
            principal_resource__name=resource,
        )
        return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists()

    def dispatch(self, request, *args, **kwargs):
        if not self.has_resource_permission(request.user, self.resource):
            # logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}")
            raise PermissionDenied("You do not have permission to access this resource.")
        return super().dispatch(request, *args, **kwargs)

    @classmethod
    def as_decorator(cls, resource):
        def decorator(view_func):
            @wraps(view_func)
            def _wrapped_view(request, *args, **kwargs):
                instance = cls()
                instance.resource = resource
                if not instance.has_resource_permission(request.user, instance.resource):
                    raise PermissionDenied("You do not have permission to access this resource.")
                return view_func(request, *args, **kwargs)
            return _wrapped_view
        return decorator
