"""P1 (assessment §3 #10 + §4 N7) — MOU expiry sweep + renewal reminder dedup.

Coverage:
- ``expire_mous`` flips ACTIVE MOUs past expires_on into EXPIRED.
- A still-active MOU is not touched.
- ``remind_mou_renewals`` fires for an MOU within the 30-day window and sets
  ``last_renewal_reminder_at``.
- Re-running ``remind_mou_renewals`` immediately is a no-op (7-day dedup).
"""
from __future__ import annotations

from datetime import timedelta

import pytest
from django.utils import timezone

from apps.rims.operations.models import MOU, Partner
from apps.rims.operations.tasks import expire_mous, remind_mou_renewals


@pytest.fixture
def partner(db):
    return Partner.objects.create(name="P1 Partner", partner_type=Partner.PartnerType.FUNDER)


@pytest.mark.django_db
def test_expire_mous_flips_past_due(partner):
    yesterday = timezone.now().date() - timedelta(days=1)
    mou = MOU.objects.create(
        partner=partner,
        title="Expired MOU",
        status=MOU.Status.ACTIVE,
        expires_on=yesterday,
    )
    flipped = expire_mous()
    mou.refresh_from_db()
    assert flipped == 1
    assert mou.status == MOU.Status.EXPIRED


@pytest.mark.django_db
def test_expire_mous_leaves_active_mou_alone(partner):
    future = timezone.now().date() + timedelta(days=60)
    mou = MOU.objects.create(
        partner=partner,
        title="Healthy MOU",
        status=MOU.Status.ACTIVE,
        expires_on=future,
    )
    flipped = expire_mous()
    mou.refresh_from_db()
    assert flipped == 0
    assert mou.status == MOU.Status.ACTIVE


@pytest.mark.django_db
def test_renewal_reminder_fires_within_30d_window(partner, grants_manager_user):
    # Need an admin recipient so the bulk_notify call has someone to email.
    from apps.core.permissions.roles import UserRole

    grants_manager_user.role = UserRole.ADMIN
    grants_manager_user.save()

    in_two_weeks = timezone.now().date() + timedelta(days=14)
    mou = MOU.objects.create(
        partner=partner,
        title="Renewal soon",
        status=MOU.Status.ACTIVE,
        expires_on=in_two_weeks,
    )
    sent = remind_mou_renewals()
    mou.refresh_from_db()
    assert sent == 1
    assert mou.last_renewal_reminder_at is not None


@pytest.mark.django_db
def test_renewal_reminder_dedup_window(partner, grants_manager_user):
    from apps.core.permissions.roles import UserRole

    grants_manager_user.role = UserRole.ADMIN
    grants_manager_user.save()

    in_two_weeks = timezone.now().date() + timedelta(days=14)
    MOU.objects.create(
        partner=partner,
        title="Renewal soon",
        status=MOU.Status.ACTIVE,
        expires_on=in_two_weeks,
    )
    first = remind_mou_renewals()
    second = remind_mou_renewals()
    assert first == 1
    assert second == 0  # 7-day dedup blocks the second run
