from django.conf import settings
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.http import Http404, HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse

from .forms import CleanupExecutionForm, CleanupPreviewForm
from .models import DatabaseCleanupOperation
from .services import (
    build_group_sections,
    execute_cleanup,
    full_reset_enabled,
    maintenance_enabled,
    preview_cleanup,
)


def database_maintenance_permission(request):
    return bool(request.user and request.user.is_superuser)


def _require_superuser(request):
    if not request.user.is_authenticated or not request.user.is_superuser:
        return False
    return True


@staff_member_required
def database_maintenance_center(request):
    if not _require_superuser(request):
        return HttpResponseForbidden("Esta área é exclusiva para superutilizadores.")

    enabled = maintenance_enabled()
    allow_full = full_reset_enabled()

    if request.method == "POST":
        if not enabled:
            messages.error(request, "A manutenção destrutiva da base de dados está desativada neste ambiente.")
            return redirect("database_maintenance_center")
        form = CleanupPreviewForm(request.POST, full_reset_allowed=allow_full)
        if form.is_valid():
            mode = form.cleaned_data["mode"]
            options = {
                "create_backup": form.cleaned_data["create_backup"],
                "delete_files": form.cleaned_data["delete_files"],
                "preserve_configuration": form.cleaned_data["preserve_configuration"] if mode == "full" else False,
                "preserve_templates": form.cleaned_data["preserve_templates"] if mode == "full" else False,
                "preserve_automation": form.cleaned_data["preserve_automation"] if mode == "full" else False,
                "preserve_other_staff": form.cleaned_data["preserve_other_staff"] if mode == "full" else False,
            }
            preview = preview_cleanup(form.cleaned_data["groups"], request.user, options)
            operation = DatabaseCleanupOperation.objects.create(
                mode=mode,
                requested_by=request.user,
                selected_groups=preview["selected_groups"],
                effective_groups=preview["effective_groups"],
                options=options,
                preview=preview,
            )
            return redirect("database_maintenance_confirm", pk=operation.pk)
    else:
        form = CleanupPreviewForm(full_reset_allowed=allow_full, initial={"mode": "selective"})

    context = {
        **getattr(settings, "UNFOLD", {}),
        "title": "Manutenção da base de dados",
        "enabled": enabled,
        "allow_full": allow_full,
        "form": form,
        "sections": build_group_sections(request.user),
        "recent_operations": DatabaseCleanupOperation.objects.select_related("requested_by")[:8],
        "version": getattr(settings, "K4W_VERSION", ""),
    }
    return render(request, "admin/maintenance/database_center.html", context)


@staff_member_required
def database_maintenance_confirm(request, pk):
    if not _require_superuser(request):
        return HttpResponseForbidden("Esta área é exclusiva para superutilizadores.")
    operation = get_object_or_404(DatabaseCleanupOperation, pk=pk)
    if operation.status != DatabaseCleanupOperation.Status.PREVIEWED:
        return redirect("database_maintenance_result", pk=operation.pk)

    expected_phrase = "LIMPAR BASE DE DADOS" if operation.mode == DatabaseCleanupOperation.Mode.FULL else "ELIMINAR SELECIONADOS"

    if request.method == "POST":
        form = CleanupExecutionForm(request.POST)
        if form.is_valid():
            if form.cleaned_data["confirmation"].strip() != expected_phrase:
                form.add_error("confirmation", f'Escreva exatamente: {expected_phrase}')
            elif not request.user.check_password(form.cleaned_data["password"]):
                form.add_error("password", "A palavra-passe do administrador não está correta.")
            elif not maintenance_enabled():
                form.add_error(None, "A manutenção destrutiva foi entretanto desativada.")
            else:
                try:
                    execute_cleanup(operation, request.user, request.session.session_key or "")
                except Exception as exc:
                    messages.error(request, f"A operação falhou: {exc}")
                else:
                    messages.success(request, "A operação de limpeza foi concluída.")
                return redirect("database_maintenance_result", pk=operation.pk)
    else:
        form = CleanupExecutionForm()

    context = {
        "title": "Confirmar operação destrutiva",
        "operation": operation,
        "preview": operation.preview,
        "expected_phrase": expected_phrase,
        "form": form,
    }
    return render(request, "admin/maintenance/database_confirm.html", context)


@staff_member_required
def database_maintenance_result(request, pk):
    if not _require_superuser(request):
        return HttpResponseForbidden("Esta área é exclusiva para superutilizadores.")
    operation = get_object_or_404(DatabaseCleanupOperation, pk=pk)
    return render(
        request,
        "admin/maintenance/database_result.html",
        {
            "title": "Resultado da manutenção",
            "operation": operation,
            "back_url": reverse("database_maintenance_center"),
        },
    )
