"""Smoke tests for operations list-view table upgrades (sort + CSV).

Verifies each list view: 200 OK on the index, ?sort=<allowed> round-trips,
?sort=<bogus> falls back to default, ?export=csv returns text/csv.
"""

from __future__ import annotations

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

from apps.core.authentication.models import MFADevice
from apps.core.permissions.roles import UserRole


def _bypass_mfa(user):
    MFADevice.objects.get_or_create(
        user=user,
        device_type=MFADevice.DeviceType.TOTP,
        defaults={"name": "Test TOTP", "secret": "JBSWY3DPEHPK3PXP", "is_verified": True},
    )


@pytest.fixture
def admin_user(db):
    User = get_user_model()
    u = User.objects.create_user(email="admin.tableupgrade@example.com", password="pw-tu")
    u.role = UserRole.ADMIN
    u.is_staff = True
    u.save()
    return u


@pytest.mark.django_db
@pytest.mark.parametrize(
    "url_name,sort_key",
    [
        ("rims_operations:partner_list", "name"),
        ("rims_operations:institution_list", "name"),
        ("rims_operations:mou_list", "title"),
        ("rims_operations:donor_list", "name"),
        ("rims_operations:strategic_objective_list", "name"),
        ("rims_operations:audit_log", "when"),
    ],
)
def test_list_view_smoke(client, admin_user, url_name, sort_key):
    _bypass_mfa(admin_user)
    client.force_login(admin_user)
    url = reverse(url_name)
    assert client.get(url).status_code == 200
    assert client.get(f"{url}?sort={sort_key}").status_code == 200
    assert client.get(f"{url}?sort=-{sort_key}").status_code == 200
    assert client.get(f"{url}?sort=bogus_field").status_code == 200


@pytest.mark.django_db
@pytest.mark.parametrize(
    "url_name",
    [
        "rims_operations:partner_list",
        "rims_operations:institution_list",
        "rims_operations:mou_list",
        "rims_operations:donor_list",
        "rims_operations:strategic_objective_list",
        "rims_operations:audit_log",
    ],
)
def test_list_view_csv_export(client, admin_user, url_name):
    _bypass_mfa(admin_user)
    client.force_login(admin_user)
    resp = client.get(reverse(url_name) + "?export=csv")
    assert resp.status_code == 200
    assert resp["Content-Type"].startswith("text/csv")
    body = resp.content.decode()
    # Header row at minimum
    assert "\n" in body or body.count(",") >= 1


@pytest.mark.django_db
@pytest.mark.parametrize(
    "url_name",
    [
        "rims_operations:donor_list",
        "rims_operations:partner_list",
        "rims_operations:strategic_objective_list",
    ],
)
def test_list_view_xlsx_export(client, admin_user, url_name):
    _bypass_mfa(admin_user)
    client.force_login(admin_user)
    resp = client.get(reverse(url_name) + "?export=xlsx")
    assert resp.status_code == 200
    assert resp["Content-Type"] == (
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    )
    # XLSX is a ZIP container — first 2 bytes are PK.
    assert resp.content[:2] == b"PK"


@pytest.mark.django_db
@pytest.mark.parametrize(
    "url_name",
    [
        "rims_operations:donor_list",
        "rims_operations:strategic_objective_list",
    ],
)
def test_htmx_request_returns_partial_only(client, admin_user, url_name):
    """When HX-Request header is present, the view should return the rows
    partial — no full layout wrapper, no <html> tag."""
    _bypass_mfa(admin_user)
    client.force_login(admin_user)
    resp = client.get(reverse(url_name) + "?q=test", HTTP_HX_REQUEST="true")
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "<html" not in body.lower()
