"""Old-system parity: legacy grants_applications.Collaborator,
grants.GrantComment, grants.Studentmembership.
"""
from datetime import date, timedelta
from decimal import Decimal

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

from apps.core.permissions.roles import UserRole
from apps.rims.grants.models import (
    Application,
    ApplicationCollaborator,
    AwardComment,
    AwardStudentMembership,
    GrantCall,
)
from apps.rims.grants.services import award_application, shortlist_application, submit_application

User = get_user_model()


def _award_for(applicant_user, institution, *, suffix="acm"):
    call = GrantCall.objects.create(
        title="Collaborators call",
        slug=f"acm-{suffix}-{int(timezone.now().timestamp())}",
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=10),
        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("1000"), date.today() + timedelta(days=180), narrative="")
    return Application.objects.get(pk=app.pk).award


@pytest.mark.django_db
def test_application_collaborator(applicant_user, institution):
    call = GrantCall.objects.create(
        title="Collab call",
        slug=f"collab-{int(timezone.now().timestamp())}",
        opens_at=timezone.now(),
        closes_at=timezone.now() + timedelta(days=10),
        status=GrantCall.Status.PUBLISHED,
    )
    app = Application.objects.create(call=call, applicant=applicant_user, institution=institution)
    collaborator = ApplicationCollaborator.objects.create(
        application=app, full_name="Dr Jane Co-PI", role="Co-Investigator"
    )
    assert app.collaborators.count() == 1
    assert collaborator.full_name == "Dr Jane Co-PI"


@pytest.mark.django_db
def test_award_comment_thread(applicant_user, institution, grants_manager_user):
    award = _award_for(applicant_user, institution, suffix="comment")
    AwardComment.objects.create(award=award, comment="Kickoff meeting held.", created_by=grants_manager_user)
    AwardComment.objects.create(award=award, comment="First tranche released.", created_by=grants_manager_user)
    assert award.comments.count() == 2
    assert list(award.comments.values_list("comment", flat=True)) == [
        "Kickoff meeting held.",
        "First tranche released.",
    ]


@pytest.mark.django_db
def test_award_supports_multiple_student_memberships(applicant_user, institution):
    award = _award_for(applicant_user, institution, suffix="membership")
    student_a = User.objects.create_user(email="student.a@test.local", password="pw")
    student_a.role = UserRole.APPLICANT
    student_a.save()
    student_b = User.objects.create_user(email="student.b@test.local", password="pw")
    student_b.role = UserRole.APPLICANT
    student_b.save()

    AwardStudentMembership.objects.create(
        award=award,
        student=student_a,
        study_year=AwardStudentMembership.StudyYear.FIRST,
        support_type=AwardStudentMembership.SupportType.RESEARCH_ONLY,
    )
    AwardStudentMembership.objects.create(
        award=award,
        student=student_b,
        study_year=AwardStudentMembership.StudyYear.THIRD,
        support_type=AwardStudentMembership.SupportType.TUITION_ONLY,
    )
    assert award.student_memberships.count() == 2


@pytest.mark.django_db
def test_award_student_membership_unique_per_student(applicant_user, institution):
    award = _award_for(applicant_user, institution, suffix="unique")
    student = User.objects.create_user(email="student.c@test.local", password="pw")
    AwardStudentMembership.objects.create(award=award, student=student)
    with pytest.raises(Exception):
        AwardStudentMembership.objects.create(award=award, student=student)
