from django.contrib.auth.mixins import AccessMixin
from django.core.exceptions import PermissionDenied
from django.utils.http import url_has_allowed_host_and_scheme

from apps.accounts import permissions as perms


class BackofficeMixin(AccessMixin):
    """Accès réservé à la rédaction ; `permission` affine selon le rôle."""

    permission = staticmethod(perms.can_access_backoffice)

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return self.handle_no_permission()
        if not perms.can_access_backoffice(request.user) or not self.permission(request.user):
            raise PermissionDenied("Accès non autorisé.")
        return super().dispatch(request, *args, **kwargs)


class EditeurRequiredMixin(BackofficeMixin):
    permission = staticmethod(perms.is_editeur)


class AdminRequiredMixin(BackofficeMixin):
    permission = staticmethod(perms.is_admin)


def safe_next(request, default):
    nxt = request.POST.get("next") or request.GET.get("next")
    if nxt and url_has_allowed_host_and_scheme(nxt, allowed_hosts={request.get_host()}, require_https=request.is_secure()):
        return nxt
    return default
