"""
Última actividad de la sesión en curso.

Se escribe de forma diferida y no en cada petición: una tabla que recibe un
UPDATE por click no aporta nada que «hace unos minutos» no cuente igual, y a
cambio convierte cada navegación en una escritura. El reloj de la última
escritura viaja dentro de la propia sesión, que ya viene cargada, así que el
caso normal no agrega ni una consulta.
"""

from django.conf import settings
from django.utils import timezone

from apps.accounts.services import touch_session

#: Marca dentro de la sesión con el instante de la última escritura.
ACTIVITY_KEY = '_last_activity'


def session_activity_middleware(get_response):
    def middleware(request):
        _record_activity(request)
        return get_response(request)

    return middleware


def _record_activity(request) -> None:
    user = getattr(request, 'user', None)
    if user is None or not user.is_authenticated:
        return

    # Sin clave no hay sesión de navegador: es el caso de la API pública
    # autenticada por clave, que no abre ninguna y no tiene qué actualizar.
    session_key = request.session.session_key
    if not session_key:
        return

    now = timezone.now()
    last = request.session.get(ACTIVITY_KEY)
    if last and now.timestamp() - last < settings.SESSION_ACTIVITY_RESOLUTION_SECONDS:
        return

    request.session[ACTIVITY_KEY] = now.timestamp()
    touch_session(session_key)
