"""
Admin building blocks for downstream sites.

Nothing is registered here — Alliance Auth ships its own ``UserAdmin``
with extra tabs and actions, so blindly re-registering the User model
would clobber that customisation. Instead, this module exposes
:class:`PlaceholderEmailFilter` as a public component; deployments
that want to surface the filter in their User list can attach it to
the existing ``UserAdmin.list_filter`` from ``local.py``::

    from django.contrib import admin
    from django.contrib.auth import get_user_model
    from aa_skip_email.admin import PlaceholderEmailFilter

    User = get_user_model()
    UserAdmin = admin.site._registry[User].__class__
    UserAdmin.list_filter = (*UserAdmin.list_filter, PlaceholderEmailFilter)
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from django.contrib import admin
from django.db.models import Q
from django.utils.translation import gettext_lazy as _

from aa_skip_email.helpers import get_placeholder_users

if TYPE_CHECKING:
    from django.db.models import QuerySet
    from django.http import HttpRequest
    from django.utils.functional import Promise


class PlaceholderEmailFilter(admin.SimpleListFilter):
    """
    Filter users by the type of value in their ``email`` field.

    Three buckets — placeholder (generated by this plugin), real
    (anything else with a value), and blank (NULL or empty). The
    boundaries match the predicates in :func:`get_placeholder_users`
    and the management command's ``--only-placeholders`` filter.
    """

    title = _("email type")
    parameter_name = "email_type"

    def lookups(
        self, request: HttpRequest, model_admin: Any
    ) -> list[tuple[str, str | Promise]]:
        """Return the choices that appear in the admin sidebar."""
        return [
            ("placeholder", _("Placeholder")),
            ("real", _("Real")),
            ("blank", _("Blank / NULL")),
        ]

    def queryset(
        self, request: HttpRequest, queryset: QuerySet[Any]
    ) -> QuerySet[Any] | None:
        """Narrow the user queryset to the chosen bucket."""
        # Django 5.x wraps SimpleListFilter values in a list to support
        # multi-value `__in` filters; our buckets are mutually exclusive,
        # so collapse to a scalar before dispatching.
        raw = self.value()
        value = raw[0] if isinstance(raw, list) else raw
        # Match against the queryset's PK set so the filter composes
        # with whatever is_staff/etc. filters are also active. Using
        # get_placeholder_users() here keeps the placeholder predicate
        # in lockstep with helpers.is_placeholder_email.
        match value:
            case "placeholder":
                placeholder_pks = get_placeholder_users().values("pk")
                return queryset.filter(pk__in=placeholder_pks)
            case "real":
                placeholder_pks = get_placeholder_users().values("pk")
                return queryset.exclude(pk__in=placeholder_pks).exclude(
                    Q(email__isnull=True) | Q(email="")
                )
            case "blank":
                return queryset.filter(Q(email__isnull=True) | Q(email=""))
            case _:
                return None
