"""
Panel interno de la cuenta.

Por ahora sólo las sesiones: es lo que FR-045 pide poder cerrar desde acá
—cuenta comprometida, credencial filtrada— sin depender de que su titular
entre a hacerlo.
"""

from django.contrib import admin, messages

from apps.accounts.models import Session
from apps.accounts.services import close_sessions


@admin.register(Session)
class SessionAdmin(admin.ModelAdmin):
    list_display = ['account', 'ip_address', 'user_agent', 'last_activity_at', 'revoked_at']
    list_filter = ['revoked_at']
    search_fields = ['account__email', 'ip_address']
    # Todo se escribe desde el flujo de ingreso o desde la acción de cierre: a
    # mano sólo se podría desincronizar la fila del almacén de sesiones.
    readonly_fields = [
        'account',
        'session_key',
        'ip_address',
        'user_agent',
        'last_activity_at',
        'revoked_at',
        'created_at',
        'updated_at',
    ]
    actions = ['close_account_sessions']

    def has_add_permission(self, request):
        return False

    @admin.action(description='Cerrar todas las sesiones de estas cuentas')
    def close_account_sessions(self, request, queryset):
        """
        Cierra la cuenta entera y no sólo las filas marcadas.

        Ante una cuenta comprometida, cerrar una sesión y dejar las otras tres
        abiertas no resuelve nada: quien entró sigue adentro por cualquiera de
        las que quedaron.
        """
        accounts = {session.account for session in queryset.select_related('account')}
        closed = sum(close_sessions(account) for account in accounts)

        self.message_user(
            request,
            f'Cerramos {closed} sesiones de {len(accounts)} cuentas.',
            messages.SUCCESS,
        )
