from django.contrib import admin
from django.contrib.auth.mixins import AccessMixin
from django.core.exceptions import PermissionDenied
from user_roles.services import RoleService


class RoleBasedAdminMixin:
    """
    Миксин для ModelAdmin с проверкой ролей.

    Использование:
        class MyAdmin(RoleBasedAdminMixin, admin.ModelAdmin):
            required_roles = ['owner', 'manager']
    """
    required_roles = []  # Роли, которые имеют доступ

    def has_module_permission(self, request):
        """Проверка доступа к модулю"""
        if not super().has_module_permission(request):
            return False

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return True

        if not self.required_roles:
            return True  # Нет ограничений

        return RoleService.user_has_role(request.user, *self.required_roles)

    def has_view_permission(self, request, obj=None):
        """Проверка доступа на просмотр"""
        if not super().has_view_permission(request, obj):
            return False

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return True

        if not self.required_roles:
            return True

        return RoleService.user_has_role(request.user, *self.required_roles)

    def has_add_permission(self, request):
        """Проверка доступа на добавление"""
        if not super().has_add_permission(request):
            return False

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return True

        if not self.required_roles:
            return True

        return RoleService.user_has_role(request.user, *self.required_roles)

    def has_change_permission(self, request, obj=None):
        """Проверка доступа на изменение"""
        if not super().has_change_permission(request, obj):
            return False

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return True

        if not self.required_roles:
            return True

        return RoleService.user_has_role(request.user, *self.required_roles)

    def has_delete_permission(self, request, obj=None):
        """Проверка доступа на удаление"""
        if not super().has_delete_permission(request, obj):
            return False

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return True

        if not self.required_roles:
            return True

        return RoleService.user_has_role(request.user, *self.required_roles)


class OwnerOnlyAdminMixin(RoleBasedAdminMixin):
    """Миксин для админки, доступной только владельцу"""
    required_roles = ['owner']


class ManagerOwnerAdminMixin(RoleBasedAdminMixin):
    """Миксин для админки, доступной менеджеру и владельцу"""
    required_roles = ['owner', 'manager']


# Миксины для обычных views (не админки)

class RoleRequiredMixin(AccessMixin):
    """
    Миксин для проверки ролей в обычных CBV.

    Использование:
        class MyView(RoleRequiredMixin, ListView):
            required_roles = ['owner', 'manager']
    """
    required_roles = []  # Список ролей, которым разрешен доступ

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return self.handle_no_permission()

        # Superuser имеет полный доступ
        if request.user.is_superuser:
            return super().dispatch(request, *args, **kwargs)

        # Если роли не указаны, доступ разрешен всем аутентифицированным
        if not self.required_roles:
            return super().dispatch(request, *args, **kwargs)

        # Проверяем роль пользователя
        if not RoleService.user_has_role(request.user, *self.required_roles):
            raise PermissionDenied("У вас нет прав для доступа к этой странице")

        return super().dispatch(request, *args, **kwargs)


class OwnerRequiredMixin(RoleRequiredMixin):
    """Миксин для view, доступного только владельцу"""
    required_roles = ['owner']


class ManagerOwnerRequiredMixin(RoleRequiredMixin):
    """Миксин для view, доступного менеджеру и владельцу"""
    required_roles = ['owner', 'manager']
