"""Verify integration outbox + notifications fire on key transitions."""

from __future__ import annotations

import pytest

from apps.repository.documents import services
from apps.repository.documents.models import Document, IntegrationOutbox


@pytest.mark.django_db
def test_publish_enqueues_mel_outbox(submitter_user, manager_user, public_collection, sample_pdf):
    doc = services.ingest_document(
        file=sample_pdf,
        title="MEL push test",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="abstract",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    services.submit_for_qa(doc, actor=submitter_user)
    services.decide_qa(doc.qa_records.first(), decision="approve", actor=manager_user, checklist=services.full_qa_checklist())

    rows = IntegrationOutbox.objects.filter(target=IntegrationOutbox.Target.MEL, event_type="document_published")
    assert rows.exists()
    payload = rows.first().payload
    assert payload["public_document_id"] == doc.public_document_id
    assert payload["collection"] == public_collection.slug


@pytest.mark.django_db
def test_withdraw_enqueues_rep_notification(submitter_user, manager_user, public_collection, sample_pdf):
    doc = services.ingest_document(
        file=sample_pdf,
        title="Withdraw notification",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="abstract",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    services.submit_for_qa(doc, actor=submitter_user)
    services.decide_qa(doc.qa_records.first(), decision="approve", actor=manager_user, checklist=services.full_qa_checklist())

    services.withdraw_document(doc, reason="Outdated.", actor=manager_user)
    assert IntegrationOutbox.objects.filter(
        target=IntegrationOutbox.Target.REP, event_type="document_withdrawn"
    ).exists()
    payload = IntegrationOutbox.objects.get(
        target=IntegrationOutbox.Target.REP, event_type="document_withdrawn"
    ).payload
    assert payload["document_uid"] == str(doc.document_uid)
    assert payload["reason"] == "Outdated."


@pytest.mark.django_db
def test_reinstate_sends_signal_and_enqueues_rep_outbox(submitter_user, manager_user, public_collection, sample_pdf):
    """reinstate_document() fires document_reinstated + queues a REP outbox row
    so any OERLink broken-flags raised on withdrawal get cleared."""
    doc = services.ingest_document(
        file=sample_pdf,
        title="Reinstate notification",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="abstract",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    services.submit_for_qa(doc, actor=submitter_user)
    services.decide_qa(doc.qa_records.first(), decision="approve", actor=manager_user, checklist=services.full_qa_checklist())
    services.withdraw_document(doc, reason="Outdated.", actor=manager_user)
    assert not IntegrationOutbox.objects.filter(
        target=IntegrationOutbox.Target.REP, event_type="document_reinstated"
    ).exists()

    services.reinstate_document(doc, reason="Reinstated after review.", actor=manager_user)

    rows = IntegrationOutbox.objects.filter(
        target=IntegrationOutbox.Target.REP, event_type="document_reinstated"
    )
    assert rows.exists()
    payload = rows.first().payload
    assert payload["document_uid"] == str(doc.document_uid)
