"""PRD §5.1 FRFA-CS031 — automatic call closure at deadline."""
from datetime import timedelta

import pytest
from django.utils import timezone

from apps.rims.grants.models import Application, GrantCall
from apps.rims.grants.tasks import close_expired_calls


@pytest.mark.django_db
def test_close_expired_calls_transitions_published_past_deadline(institution):
    expired = GrantCall.objects.create(
        title="Expired call",
        slug=f"expired-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=10),
        closes_at=timezone.now() - timedelta(minutes=5),
        status=GrantCall.Status.PUBLISHED,
    )
    active = GrantCall.objects.create(
        title="Still open",
        slug=f"open-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=5),
        status=GrantCall.Status.PUBLISHED,
    )
    closed = close_expired_calls()
    assert closed == 1
    expired = GrantCall.objects.get(pk=expired.pk)
    active = GrantCall.objects.get(pk=active.pk)
    assert expired.status == GrantCall.Status.CLOSED
    assert active.status == GrantCall.Status.PUBLISHED


@pytest.mark.django_db
def test_close_expired_calls_is_idempotent(institution):
    """Re-running the sweep must not transition already-closed calls."""
    call = GrantCall.objects.create(
        title="Double close",
        slug=f"double-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=2),
        closes_at=timezone.now() - timedelta(hours=1),
        status=GrantCall.Status.PUBLISHED,
    )
    assert close_expired_calls() == 1
    call = GrantCall.objects.get(pk=call.pk)
    assert call.status == GrantCall.Status.CLOSED
    # Second run finds no PUBLISHED calls past deadline.
    assert close_expired_calls() == 0


@pytest.mark.django_db
def test_close_expired_calls_skips_non_published(institution):
    GrantCall.objects.create(
        title="Draft past deadline",
        slug=f"draft-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=10),
        closes_at=timezone.now() - timedelta(minutes=5),
        status=GrantCall.Status.DRAFT,
    )
    assert close_expired_calls() == 0


@pytest.mark.django_db
def test_submitted_applications_are_not_disturbed_by_auto_close(
    applicant_user, institution
):
    """Auto-close flips call lifecycle only; already-submitted applications
    stay where they are."""
    from apps.rims.grants.services import submit_application

    call = GrantCall.objects.create(
        title="Preserve submitted",
        slug=f"preserve-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=10),
        closes_at=timezone.now() + timedelta(days=5),
        status=GrantCall.Status.PUBLISHED,
    )
    app = Application.objects.create(call=call, applicant=applicant_user, institution=institution)
    submit_application(app)
    app = Application.objects.get(pk=app.pk)
    submitted_status = app.status

    # Move the deadline into the past and sweep.
    call.closes_at = timezone.now() - timedelta(minutes=1)
    call.save(update_fields=["closes_at"])
    close_expired_calls()

    call = GrantCall.objects.get(pk=call.pk)
    app = Application.objects.get(pk=app.pk)
    assert call.status == GrantCall.Status.CLOSED
    assert app.status == submitted_status
