"""PERF-002: EventSerializer.get_attendees_count must read a queryset
annotation, not issue one .count() query per row. Regression: 122 queries
for 120 events before the fix."""
from datetime import datetime, timedelta

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

from apps.events.models import Event, EventRegistration

User = get_user_model()


@pytest.fixture
def client(db):
    admin = User.objects.create_superuser(email="events-admin@test.local", password="x")
    c = APIClient()
    c.force_authenticate(admin)
    c.admin = admin
    return c


@pytest.fixture
def organization(client):
    return client.admin.organizations.get()


def _make_event(organization, organizer, name):
    start = datetime.now()
    return Event.objects.create(
        organization=organization, name=name, event_type="conference",
        start_date=start, end_date=start + timedelta(hours=2), organizer=organizer,
    )


@pytest.mark.django_db
class TestEventListQueryCount:
    def test_query_count_constant_as_events_grow(self, client, organization):
        e1 = _make_event(organization, client.admin, "Event 1")
        EventRegistration.objects.create(event=e1, name="A", email="a@x.com", status="registered")
        EventRegistration.objects.create(event=e1, name="B", email="b@x.com", status="checked_in")
        EventRegistration.objects.create(event=e1, name="C", email="c@x.com", status="registered")

        with CaptureQueriesContext(connection) as small:
            client.get("/api/events/")

        for i in range(2, 121):
            e = _make_event(organization, client.admin, f"Event {i}")
            EventRegistration.objects.create(event=e, name=f"P{i}", email=f"p{i}@x.com", status="registered")

        with CaptureQueriesContext(connection) as big:
            client.get("/api/events/")

        assert len(big.captured_queries) == len(small.captured_queries)
        # PERF-007: deterministic CI gate — fixed ceiling independent of
        # collection growth (auth, permissions, org resolution, the
        # annotated event query itself; EventViewSet has no pagination yet
        # so there's no separate COUNT query to budget for).
        assert len(big.captured_queries) <= 12, (
            f"expected <=12 queries for the event list, got {len(big.captured_queries)}"
        )

    def test_attendees_count_correct_for_mixed_statuses(self, client, organization):
        event = _make_event(organization, client.admin, "Mixed")
        EventRegistration.objects.create(event=event, name="A", email="a@x.com", status="registered")
        EventRegistration.objects.create(event=event, name="B", email="b@x.com", status="checked_in")
        EventRegistration.objects.create(event=event, name="C", email="c@x.com", status="rejected")

        resp = client.get("/api/events/")
        rows = resp.json()
        rows = rows["results"] if isinstance(rows, dict) and "results" in rows else rows
        row = next(r for r in rows if r["id"].replace("-", "") == str(event.id).replace("-", ""))
        assert row["attendees_count"] == 2

    def test_attendees_count_zero_when_no_registrations(self, client, organization):
        event = _make_event(organization, client.admin, "Empty")
        resp = client.get("/api/events/")
        rows = resp.json()
        rows = rows["results"] if isinstance(rows, dict) and "results" in rows else rows
        row = next(r for r in rows if r["id"].replace("-", "") == str(event.id).replace("-", ""))
        assert row["attendees_count"] == 0
