from __future__ import annotations

from django.contrib import messages
from django.shortcuts import redirect
from django.urls import reverse

from clients.models import ClientPortalAccess

SESSION_ACCESS_ID = "k4w_client_preview_access_id"
SESSION_INTERACTIVE = "k4w_client_preview_interactive"
SESSION_RETURN_URL = "k4w_client_preview_return_url"


def preview_access(request):
    """Return the client access currently previewed by a staff user."""
    user = getattr(request, "user", None)
    if not user or not user.is_authenticated or not user.is_staff:
        return None
    access_id = request.session.get(SESSION_ACCESS_ID)
    if not access_id:
        return None
    try:
        return (
            ClientPortalAccess.objects.select_related("client", "user")
            .get(pk=access_id)
        )
    except ClientPortalAccess.DoesNotExist:
        clear_preview(request)
        return None


def is_preview(request):
    return preview_access(request) is not None


def is_interactive(request):
    return bool(is_preview(request) and request.session.get(SESSION_INTERACTIVE, False))


def start_preview(request, access: ClientPortalAccess, *, interactive: bool = False):
    request.session[SESSION_ACCESS_ID] = access.pk
    request.session[SESSION_INTERACTIVE] = bool(interactive)
    request.session[SESSION_RETURN_URL] = reverse("client_preview_center")
    request.session.modified = True


def clear_preview(request):
    for key in (SESSION_ACCESS_ID, SESSION_INTERACTIVE, SESSION_RETURN_URL):
        request.session.pop(key, None)
    request.session.modified = True


def preview_return_url(request):
    return request.session.get(SESSION_RETURN_URL) or reverse("client_preview_center")


def require_preview_write(request):
    """Block state-changing actions while a read-only preview is active."""
    if is_preview(request) and not is_interactive(request):
        messages.warning(
            request,
            "A pré-visualização está em modo só de leitura. Ative o teste interativo no backoffice para executar esta ação.",
        )
        return redirect(request.META.get("HTTP_REFERER") or "client_portal:dashboard")
    return None
