from datetime import timedelta
from decimal import Decimal

import pytest
from django.urls import reverse
from django.utils import timezone

from apps.rims.grants.models import Application, Award, GrantCall
from apps.rims.grants.services import award_application, shortlist_application, submit_application
from apps.rims.projects.models import Milestone, Project


@pytest.mark.django_db
def test_award_closeout_blocked_by_unresolved_required_milestones(
    client, grants_manager_user, applicant_user, institution
):
    call = GrantCall.objects.create(
        title="Closeout gate call",
        slug=f"closeout-gate-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=15),
        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)
    shortlist_application(app)
    award_application(app, Decimal("1500"), timezone.now().date() + timedelta(days=180), narrative="")
    award = Application.objects.get(pk=app.pk).award
    project = Project.objects.create(
        award=award,
        title="Closeout project",
        summary="",
        start_date=timezone.now().date(),
        end_date=timezone.now().date() + timedelta(days=120),
        status=Project.Status.ACTIVE,
    )
    Milestone.objects.create(
        project=project,
        name="Pending milestone",
        due_date=timezone.now().date() + timedelta(days=7),
        report_due=True,
        status=Milestone.Status.SUBMITTED,
    )
    client.force_login(grants_manager_user)
    url = reverse("rims_grants:award_closeout", kwargs={"pk": award.pk})
    resp = client.post(
        url,
        {
            "narrative": "Final report narrative",
            "co_done__final_narrative": "on",
            "co_done__financial_reconciliation": "on",
            "co_done__no_outstanding_flags": "on",
        },
        follow=True,
    )
    assert resp.status_code == 200
    award.refresh_from_db()
    assert award.status == Award.Status.ACTIVE
