"""Tests for SessionIdleTimeoutMiddleware."""
from __future__ import annotations

import time

import pytest
from django.contrib.auth import get_user_model
from django.test import Client
from django.urls import reverse

User = get_user_model()


@pytest.fixture(autouse=True)
def _disable_axes(settings):
    settings.AXES_ENABLED = False
    yield


@pytest.fixture
def user(db):
    return User.objects.create_user(
        email="idle@example.com",
        password="x",
        first_name="A",
        last_name="B",
    )


def test_fresh_session_passes(user, settings):
    settings.SESSION_IDLE_TIMEOUT_SECONDS = 3600
    c = Client()
    c.force_login(user)
    resp = c.get(reverse("core:dashboard"))
    assert resp.status_code == 200


def test_idle_session_redirects_to_login(user, settings):
    settings.SESSION_IDLE_TIMEOUT_SECONDS = 1
    c = Client()
    c.force_login(user)
    # First request seeds _last_activity
    c.get(reverse("core:dashboard"))
    # Backdate the session so the next request is past the timeout
    s = c.session
    s["_last_activity"] = int(time.time()) - 10
    s.save()
    resp = c.get(reverse("core:dashboard"))
    assert resp.status_code == 302
    assert "reason=idle" in resp.headers["Location"]


def test_sse_traffic_does_not_refresh_timer(user, settings):
    settings.SESSION_IDLE_TIMEOUT_SECONDS = 5
    c = Client()
    c.force_login(user)
    # Seed activity
    c.get(reverse("core:dashboard"))
    seeded = c.session["_last_activity"]
    # Hit the SSE stream — must NOT update _last_activity
    c.get(reverse("core:notification_stream"))
    assert c.session.get("_last_activity") == seeded


def test_anonymous_request_passes_through(settings):
    settings.SESSION_IDLE_TIMEOUT_SECONDS = 1
    c = Client()
    resp = c.get(reverse("accounts:login"))
    assert resp.status_code == 200


def test_idle_htmx_request_returns_hx_redirect_not_302(user, settings):
    """HTMX requests must get HX-Redirect, otherwise HTMX swaps the login
    page HTML into the original target element instead of navigating."""
    settings.SESSION_IDLE_TIMEOUT_SECONDS = 1
    c = Client()
    c.force_login(user)
    c.get(reverse("core:dashboard"))
    s = c.session
    s["_last_activity"] = int(time.time()) - 10
    s.save()
    resp = c.get(reverse("core:dashboard"), HTTP_HX_REQUEST="true")
    assert resp.status_code == 200
    assert "reason=idle" in resp.headers["HX-Redirect"]
    assert "Location" not in resp.headers
