"""PRD §6.1 + FRFA-AM019 — reviewer access is scoped to assigned applications.

Regression tests that lock in object-level permission behaviour:
- A reviewer cannot load another reviewer's review by URL guessing.
- A reviewer cannot load the applicant-side detail for an application that
  isn't their own.
- A reviewer's queue lists only their own in-flight assignments.
"""
from datetime import timedelta

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

from apps.core.permissions.roles import UserRole
from apps.rims.grants.models import Application, GrantCall, Review

User = get_user_model()


@pytest.fixture
def reviewer_a(db):
    u = User.objects.create_user(email="reviewer-a@example.com", password="pw")
    u.role = UserRole.REVIEWER
    u.save()
    return u


@pytest.fixture
def reviewer_b(db):
    u = User.objects.create_user(email="reviewer-b@example.com", password="pw")
    u.role = UserRole.REVIEWER
    u.save()
    return u


def _make_app(applicant_user, institution, slug):
    call = GrantCall.objects.create(
        title="Perm test",
        slug=slug,
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=10),
        status=GrantCall.Status.PUBLISHED,
    )
    return Application.objects.create(
        call=call, applicant=applicant_user, institution=institution
    )


@pytest.mark.django_db
def test_reviewer_cannot_load_anothers_review(
    client, reviewer_a, reviewer_b, applicant_user, institution
):
    app = _make_app(applicant_user, institution, f"perm-{int(timezone.now().timestamp())}")
    review_a = Review.objects.create(application=app, reviewer=reviewer_a)

    # Reviewer B logs in and tries to open Reviewer A's review by primary key.
    client.force_login(reviewer_b)
    url = reverse("rims_grants:review_submit", kwargs={"pk": review_a.pk})
    resp = client.get(url)
    assert resp.status_code == 404


@pytest.mark.django_db
def test_reviewer_cannot_access_applicant_detail_by_url(
    client, reviewer_a, applicant_user, institution
):
    """ApplicationDetailView is scoped via get_queryset to applicant==request.user,
    which is the current object-level guard. A reviewer guessing the URL gets 404."""
    app = _make_app(applicant_user, institution, f"perm-det-{int(timezone.now().timestamp())}")
    client.force_login(reviewer_a)
    url = reverse("rims_grants:application_detail", kwargs={"pk": app.pk})
    resp = client.get(url)
    assert resp.status_code == 404


@pytest.mark.django_db
def test_reviewer_queue_lists_only_own_assignments(
    client, reviewer_a, reviewer_b, applicant_user, institution
):
    app1 = _make_app(applicant_user, institution, f"perm-q1-{int(timezone.now().timestamp())}")
    app2 = _make_app(applicant_user, institution, f"perm-q2-{int(timezone.now().timestamp())}-x")
    review_a = Review.objects.create(application=app1, reviewer=reviewer_a)
    review_b = Review.objects.create(application=app2, reviewer=reviewer_b)

    client.force_login(reviewer_a)
    resp = client.get(reverse("rims_grants:review_queue"))
    assert resp.status_code == 200
    queue = list(resp.context["reviews"])
    assert review_a in queue
    assert review_b not in queue
