"""Closes the SRS gap where Fellowship applicants had no dedicated wizard
(they shared the generic ApplyCallView while FellowshipApplicationProfile
had no UI to populate it). Covers the full happy-path flow: basic ->
placement -> documents -> review -> submit.
"""
from datetime import timedelta
from unittest.mock import patch

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

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


@pytest.fixture(autouse=True)
def _no_async_dispatch():
    with patch(
        "apps.core.notifications.services.dispatch_notification_channel.delay"
    ) as fake:
        yield fake


@pytest.fixture
def fellowship_call(db):
    return GrantCall.objects.create(
        title="Staff mobility fellowship",
        slug="fellowship-wizard-test",
        call_type=GrantCall.CallType.FELLOWSHIP,
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=14),
        status=GrantCall.Status.PUBLISHED,
    )


@pytest.mark.django_db
def test_fellowship_apply_happy_path(client, fellowship_call, applicant_user, institution):
    client.force_login(applicant_user)

    resp = client.post(
        reverse("rims_grants:fellowship_apply_step1", kwargs={"slug": fellowship_call.slug}),
        {"institution": institution.pk},
    )
    assert resp.status_code == 302
    app = Application.objects.get(call=fellowship_call, applicant=applicant_user)
    assert app.status == Application.Status.DRAFT

    resp = client.post(
        reverse("rims_grants:fellowship_apply_step2", kwargs={"slug": fellowship_call.slug, "pk": app.pk}),
        {
            "home_institute_name": "Home University",
            "host_institute_name": "Host University",
            "duration_weeks": 12,
            "subject_area": "Soil science",
        },
    )
    assert resp.status_code == 302
    profile = app.fellowship_profile
    profile.refresh_from_db()
    assert profile.home_institute_name == "Home University"
    assert profile.host_institute_name == "Host University"

    resp = client.post(
        reverse("rims_grants:fellowship_apply_step3", kwargs={"slug": fellowship_call.slug, "pk": app.pk}),
        {"proposal": "I intend to study soil regeneration techniques."},
    )
    assert resp.status_code == 302
    # Application.status is a protected FSMField — refresh_from_db() can't
    # touch it, so re-fetch instead.
    app = Application.objects.get(pk=app.pk)
    assert app.proposal == "I intend to study soil regeneration techniques."

    resp = client.post(
        reverse("rims_grants:fellowship_apply_review", kwargs={"slug": fellowship_call.slug, "pk": app.pk})
    )
    assert resp.status_code == 302
    app = Application.objects.get(pk=app.pk)
    assert app.status != Application.Status.DRAFT
