"""PRD §5.4 FRFM005 — per-line funding source assignment.

Different rows on the same budget can sit against different donors, and the
``effective_funding_source`` property returns the line override (when set)
or falls back to ``Budget.funding_source``.
"""
from datetime import date, timedelta
from decimal import Decimal

import pytest
from django.utils import timezone

from apps.rims.finance.models import Budget, BudgetLine, FundingSource
from apps.rims.grants.models import Application, GrantCall
from apps.rims.grants.services import award_application, shortlist_application, submit_application


def _award(applicant_user, institution):
    call = GrantCall.objects.create(
        title="FRFM005 call",
        slug=f"frfm005-{int(timezone.now().timestamp() * 1000) % 10_000_000}",
        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_line_can_override_budget_funding_source(applicant_user, institution):
    donor_a = FundingSource.objects.create(name="Donor A", code="donor-a")
    donor_b = FundingSource.objects.create(name="Donor B", code="donor-b")
    award = _award(applicant_user, institution)
    budget = Budget.objects.create(award=award, name="Mixed sources", funding_source=donor_a)

    inherited_line = BudgetLine.objects.create(budget=budget, label="Travel", amount=Decimal("250"))
    overridden_line = BudgetLine.objects.create(
        budget=budget, label="Equipment", amount=Decimal("750"), funding_source=donor_b
    )

    assert inherited_line.funding_source is None
    assert inherited_line.effective_funding_source == donor_a
    assert overridden_line.funding_source == donor_b
    assert overridden_line.effective_funding_source == donor_b


@pytest.mark.django_db
def test_line_effective_funding_source_with_no_budget_default(applicant_user, institution):
    award = _award(applicant_user, institution)
    budget = Budget.objects.create(award=award, name="No default")
    line = BudgetLine.objects.create(budget=budget, label="Travel", amount=Decimal("250"))
    assert line.effective_funding_source is None
