"""P1 (assessment §4 N6) — scholar status-change notification fan-out.

Coverage:
- transition_scholar emits a notification to finance + programme officer
  pool when a scholar moves into WITHDRAWN.
- The scholar's own user account also receives the update.
"""
from __future__ import annotations

import pytest
from django.contrib.auth import get_user_model

from apps.core.notifications.models import Notification
from apps.core.permissions.roles import UserRole
from apps.rims.scholarships.models import Scholar, Scholarship
from apps.rims.scholarships.workflows import transition_scholar

User = get_user_model()


@pytest.fixture
def finance_manager(db):
    u = User.objects.create_user(email="finmgr@example.com", password="pw")
    u.role = UserRole.FINANCE_MANAGER
    u.save()
    return u


@pytest.fixture
def programme_officer(db):
    u = User.objects.create_user(email="po@example.com", password="pw")
    u.role = UserRole.PROGRAMME_OFFICER
    u.save()
    return u


@pytest.fixture
def active_scholar(db, applicant_user):
    programme = Scholarship.objects.create(name="P1 MSc")
    scholar = Scholar.objects.create(user=applicant_user, scholarship=programme)
    transition_scholar(scholar, to_status=Scholar.Status.ACTIVE)
    scholar.refresh_from_db()
    return scholar


@pytest.mark.django_db
def test_withdrawal_notifies_finance_and_programme_officers(
    active_scholar, finance_manager, programme_officer, grants_manager_user
):
    transition_scholar(
        active_scholar,
        to_status=Scholar.Status.WITHDRAWN,
        actor=grants_manager_user,
        reason="audit",
    )
    fm = Notification.objects.filter(
        recipient=finance_manager,
        verb=Notification.Verb.RIMS_SCHOLAR_STATUS_CHANGED,
    )
    po = Notification.objects.filter(
        recipient=programme_officer,
        verb=Notification.Verb.RIMS_SCHOLAR_STATUS_CHANGED,
    )
    assert fm.exists()
    assert po.exists()


@pytest.mark.django_db
def test_withdrawal_notifies_scholar_themselves(active_scholar, grants_manager_user):
    transition_scholar(
        active_scholar,
        to_status=Scholar.Status.WITHDRAWN,
        actor=grants_manager_user,
        reason="leaving",
    )
    me = Notification.objects.filter(
        recipient=active_scholar.user,
        verb=Notification.Verb.RIMS_SCHOLAR_STATUS_CHANGED,
    )
    assert me.exists()
