"""Closes the SRS gap where Challenge applicants had no dedicated wizard
(they shared the generic ApplyCallView while ChallengeApplicationProfile
and ApplicationPartner had no UI to populate them). Covers the full
happy-path flow: basic -> innovation profile -> partners & 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 challenge_call(db):
    return GrantCall.objects.create(
        title="Agritech innovation challenge",
        slug="challenge-wizard-test",
        call_type=GrantCall.CallType.CHALLENGE,
        opens_at=timezone.now() - timedelta(days=1),
        closes_at=timezone.now() + timedelta(days=14),
        status=GrantCall.Status.PUBLISHED,
        challenge_innovation_stage=GrantCall.InnovationStage.PROTOTYPE,
    )


@pytest.mark.django_db
def test_challenge_apply_happy_path(client, challenge_call, applicant_user, institution):
    client.force_login(applicant_user)

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

    resp = client.post(
        reverse("rims_grants:challenge_apply_step2", kwargs={"slug": challenge_call.slug, "pk": app.pk}),
        {
            "innovation_stage": "prototype",
            "problem_statement": "Post-harvest losses among smallholders.",
            "proposed_solution": "Low-cost solar cold storage.",
            "team_size": 4,
        },
    )
    assert resp.status_code == 302
    profile = app.challenge_profile
    assert profile.problem_statement == "Post-harvest losses among smallholders."
    assert profile.team_size == 4

    resp = client.post(
        reverse("rims_grants:challenge_apply_step3", kwargs={"slug": challenge_call.slug, "pk": app.pk}),
        {
            "proposal": "Our solution reduces spoilage by 40%.",
            "partner_org_0": "Cold Chain Partners Ltd",
            "partner_contact_0": "Jane Doe",
            "partner_email_0": "jane@coldchain.example",
            "partner_phone_0": "+256700000000",
            "partner_address_0": "Kampala",
            "partner_expertise_0": "Refrigeration engineering",
        },
    )
    assert resp.status_code == 302
    assert app.partners.count() == 1
    assert app.partners.first().organization_name == "Cold Chain Partners Ltd"

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