from django.middleware.csrf import get_token
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _


class HijackUserAdminMixin:
    def get_hijack_user(self, obj):
        """
        Return the user based on the current object.

        This method may be overridden to support hijack keys on related objects.
        """
        return obj

    def hijack_button(self, request, obj):
        """
        Render hijack button.

        Should the user only be a related object we include the username in the button
        to ensure deliberate action. However, the name is omitted in the user admin,
        as the table layout suggests that the button targets the current user.
        """
        user = self.get_hijack_user(obj)
        return render_to_string(
            "hijack/contrib/admin/button.html",
            {
                "request": request,
                "csrf_token": get_token(request),
                "another_user": user,
                "username": str(user),
                "is_user_admin": self.model == type(user),
            },
        )

    hijack_button.short_description = _("hijack user")

    def get_changelist_instance(self, request):
        # We inject the request for the CSRF token, see also:
        # https://code.djangoproject.com/ticket/13659
        def hijack_field(obj):
            return self.hijack_button(request, obj)

        # we
        list_display = [*self.get_list_display(request), hijack_field]
        # Same as super method, see also:
        # https://github.com/django/django/blob/76c0b32f826469320c59709d31e2f2126dd7c505/django/contrib/admin/options.py#L724-L750
        list_display_links = self.get_list_display_links(request, list_display)
        # Add the action checkboxes if any actions are available.
        if self.get_actions(request):
            list_display = ["action_checkbox", *list_display]
        sortable_by = self.get_sortable_by(request)
        ChangeList = self.get_changelist(request)
        return ChangeList(
            request,
            self.model,
            list_display,
            list_display_links,
            self.get_list_filter(request),
            self.date_hierarchy,
            self.get_search_fields(request),
            self.get_list_select_related(request),
            self.list_per_page,
            self.list_max_show_all,
            self.list_editable,
            self,
            sortable_by,
        )
