import logging

from django import forms
from django.contrib import messages
from django.shortcuts import redirect, render
from django.urls import path
from django.utils.translation import gettext_lazy as _
from unfold.sites import UnfoldAdminSite

from core.caches import cache_instance
from core.utils.views import cache_methods_registry

logger = logging.getLogger(__name__)


class ClearCacheForm(forms.Form):
    viewset_class = forms.ChoiceField(choices=[])

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        choices = [
            (cls.__name__, cls.__name__) for cls in cache_methods_registry
        ]
        self.fields["viewset_class"].choices = choices


class MyAdminSite(UnfoldAdminSite):
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path(
                "clear-cache/",
                self.admin_view(self.clear_cache_view),
                name="clear-cache",
            ),
            path(
                "clear-site-cache/",
                self.admin_view(self.clear_site_cache_view),
                name="clear-site-cache",
            ),
        ]
        return custom_urls + urls

    def clear_cache_view(self, request):
        if request.method == "POST" and "clear_cache_for_class" in request.POST:
            form = ClearCacheForm(request.POST)
            if form.is_valid():
                selected_class = form.cleaned_data["viewset_class"]
                self.clear_cache_for_class(request, selected_class)
                return redirect("admin:clear-cache")
        elif request.method == "POST" and "clear_site_cache" in request.POST:
            results = self.clear_site_cache()
            total = sum(results.values())
            messages.success(
                request,
                _("Cleared %(total)s cache keys") % {"total": total},
            )
            return redirect("admin:clear-cache")
        else:
            form = ClearCacheForm()

        context = {
            **self.each_context(request),
            "form": form,
        }
        return render(request, "admin/clear_cache.html", context)

    @staticmethod
    def clear_cache_for_class(request, class_name):
        """Clear all raw Redis keys matching a class name pattern."""
        raw_keys = cache_instance.keys(class_name)

        if not raw_keys:
            messages.info(
                request,
                _("No keys found for %(class_name)s")
                % {"class_name": class_name},
            )
            return

        deleted_keys = cache_instance.delete_raw_keys(raw_keys)

        if deleted_keys > 0:
            messages.success(
                request,
                _("Deleted %(deleted_keys)s keys for %(class_name)s")
                % {
                    "deleted_keys": deleted_keys,
                    "class_name": class_name,
                },
            )
        else:
            messages.info(
                request,
                _("No keys found for %(class_name)s")
                % {"class_name": class_name},
            )

    def clear_site_cache_view(self, request):
        results = self.clear_site_cache()
        total = sum(results.values())
        messages.success(
            request,
            _("Cleared %(total)s cache keys") % {"total": total},
        )
        return redirect("admin:clear-cache")

    @staticmethod
    def clear_site_cache() -> dict[str, int]:
        """Clear all safe cache keys (Django + Nuxt) without FLUSHDB."""
        return cache_instance.clear_by_prefixes()
