"""AI insight chains — exercised with stubbed LLM (no OPENAI_API_KEY)."""

from __future__ import annotations

import pytest

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


@pytest.fixture(autouse=True)
def _no_api_key(settings):
    settings.OPENAI_API_KEY = ""


@pytest.mark.django_db
def test_summarise_document_stub_path(submitter_user, public_collection, sample_pdf):
    from apps.repository.analytics.ai_insights import summarise_document

    doc = services.ingest_document(
        file=sample_pdf,
        title="Sumtest",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="A short abstract.",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    insight = summarise_document(doc.pk)
    assert insight is not None
    assert insight.payload["summary"]
    fresh = Document.objects.get(pk=doc.pk)
    assert fresh.ai_summary != ""


@pytest.mark.django_db
def test_classify_document_stub_path(submitter_user, public_collection, sample_pdf):
    from apps.repository.analytics.ai_insights import classify_document

    doc = services.ingest_document(
        file=sample_pdf,
        title="Drought-tolerant maize varieties",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="An overview of drought-tolerant maize varieties.",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    insight = classify_document(doc.pk)
    assert insight is not None
    assert insight.payload["suggested_collection_slug"] == public_collection.slug
    assert isinstance(insight.payload["keywords"], list)


# ── FRREP-AR013 — AI generation events get a distinct audit-log entry ─────
#
# The actual write goes through ``log_audit`` -> ``transaction.on_commit`` ->
# a Celery task, so asserting on a persisted ``AuditLog`` row from a plain
# function call (no HTTP request/response cycle) is unreliable in this
# environment. Assert on the call contract instead: `audit_repository` is
# invoked, exactly once, with the distinct action code + the right
# target/object identifiers — that's the behaviour AR013 actually asks for.


@pytest.mark.django_db
def test_summarise_document_writes_audit_log(submitter_user, public_collection, sample_pdf):
    from unittest.mock import patch

    from apps.repository.analytics.ai_insights import summarise_document

    doc = services.ingest_document(
        file=sample_pdf,
        title="Audit summary test",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="A short abstract for audit trail testing.",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    with patch("apps.repository.documents.audit_helper.audit_repository") as mock_audit:
        insight = summarise_document(doc.pk)

    mock_audit.assert_called_once()
    kwargs = mock_audit.call_args.kwargs
    assert kwargs["actor"] is None
    assert kwargs["action"] == "AI_SUMMARY_GENERATED"
    assert kwargs["target_model"] == "AIDocumentInsight"
    assert kwargs["object_id"] == insight.pk
    assert kwargs["changes"]["document_id"] == doc.pk


@pytest.mark.django_db
def test_classify_document_writes_audit_log(submitter_user, public_collection, sample_pdf):
    from unittest.mock import patch

    from apps.repository.analytics.ai_insights import classify_document

    doc = services.ingest_document(
        file=sample_pdf,
        title="Audit classification test",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="An overview for audit trail testing.",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    with patch("apps.repository.documents.audit_helper.audit_repository") as mock_audit:
        insight = classify_document(doc.pk)

    mock_audit.assert_called_once()
    kwargs = mock_audit.call_args.kwargs
    assert kwargs["action"] == "AI_CLASSIFICATION_GENERATED"
    assert kwargs["target_model"] == "AIDocumentInsight"
    assert kwargs["object_id"] == insight.pk


@pytest.mark.django_db
def test_extract_metadata_writes_audit_log(submitter_user, public_collection, sample_pdf):
    from unittest.mock import patch

    from apps.repository.analytics.ai_insights import extract_metadata

    doc = services.ingest_document(
        file=sample_pdf,
        title="Audit metadata test",
        collection=public_collection,
        document_type=Document.DocumentType.THESIS,
        abstract="An abstract for metadata extraction audit testing.",
        submitted_by=submitter_user,
        actor=submitter_user,
    )
    with patch("apps.repository.documents.audit_helper.audit_repository") as mock_audit:
        insight = extract_metadata(doc.pk)

    mock_audit.assert_called_once()
    kwargs = mock_audit.call_args.kwargs
    assert kwargs["action"] == "AI_METADATA_EXTRACTED"
    assert kwargs["target_model"] == "AIDocumentInsight"
    assert kwargs["object_id"] == insight.pk
