"""Sidebar badges: payload shape, correctness, global-bucket caching."""

import pytest
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.db import connection
from django.test.utils import CaptureQueriesContext
from rest_framework.test import APIClient

User = get_user_model()

EXPECTED_KEYS = {
    "tasks_assigned", "task_approvals_pending", "task_my_approval_requests",
    "procurement_approvals_pending", "procurement_my_requests",
    "procurement_rfq_open", "procurement_po_open", "procurement_gr_pending",
    "procurement_invoices_unpaid", "procurement_payments_pending",
    "administration_my_requests", "car_booking_my_requests",
    "reimbursement_my_requests", "payment_request_my_requests",
    "document_request_my_requests", "helpdesk_pending", "events_upcoming",
    "project_active", "hr_recruitment_open", "asset_tickets_assigned",
    "messages", "notifications",
}


@pytest.fixture(autouse=True)
def clear_cache():
    cache.clear()
    yield
    cache.clear()


@pytest.fixture
def user(db):
    return User.objects.create_user(email="side@test.local", password="x")


@pytest.fixture
def client(user):
    c = APIClient()
    c.force_authenticate(user)
    return c


@pytest.mark.django_db
class TestSidebarBadges:
    def test_payload_shape_unchanged(self, client):
        body = client.get("/api/sidebar/badges/").json()
        assert set(body.keys()) == EXPECTED_KEYS

    def test_counts_reflect_data(self, client, user):
        from apps.tasks.models import Task
        Task.objects.create(title="T", assignee=user, created_by=user, status="todo")
        cache.clear()  # bust the 10s payload cache
        body = client.get("/api/sidebar/badges/").json()
        assert body["tasks_assigned"] == 1

    def test_global_bucket_shared_across_users(self, client, user):
        client.get("/api/sidebar/badges/")  # warms sidebar_badges:global
        other = User.objects.create_user(email="side2@test.local", password="x")
        c2 = APIClient()
        c2.force_authenticate(other)
        with CaptureQueriesContext(connection) as first_other:
            c2.get("/api/sidebar/badges/")
        cache.delete("sidebar_badges:global")
        cache.delete(f"sidebar_badges:{other.id}")
        with CaptureQueriesContext(connection) as cold_global:
            c2.get("/api/sidebar/badges/")
        # Warm global bucket → 7 org-wide count queries skipped.
        assert len(cold_global.captured_queries) - len(first_other.captured_queries) == 7
