from functools import wraps

from django.contrib.auth.views import redirect_to_login
from django.core.exceptions import PermissionDenied

from .preview import is_interactive, preview_access, require_preview_write


def portal_access_for(user):
    if not user.is_authenticated:
        return None
    try:
        access = user.client_portal_access
    except Exception:
        return None
    if not access.is_active or not access.client.portal_access_enabled:
        return None
    return access


def portal_access_for_request(request):
    preview = preview_access(request)
    if preview is not None:
        return preview
    return portal_access_for(request.user)


def client_portal_required(view):
    @wraps(view)
    def wrapped(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect_to_login(request.get_full_path(), login_url="client_portal:login")
        access = portal_access_for_request(request)
        if not access:
            raise PermissionDenied("Este utilizador não tem acesso ativo ao portal de clientes.")
        request.portal_access = access
        request.portal_client = access.client
        request.portal_actor_user = access.user
        request.portal_preview_mode = bool(request.user.is_staff and preview_access(request))
        request.portal_preview_interactive = bool(request.portal_preview_mode and is_interactive(request))
        if request.method not in {"GET", "HEAD", "OPTIONS"}:
            blocked = require_preview_write(request)
            if blocked is not None:
                return blocked
        return view(request, *args, **kwargs)

    return wrapped
