"""FRREP-SR001/004 — reindex_repository_search rebuilds stale FTS vectors."""

from __future__ import annotations

import itertools

import pytest
from django.core.management import call_command

from apps.repository.documents.models import Author, Document
from apps.repository.search.services import search_documents

_seq = itertools.count(1)


def _doc(collection, title, **kwargs):
    return Document.objects.create(
        title=title,
        collection=collection,
        status=Document.Status.PUBLISHED,
        visibility=Document.Visibility.PUBLIC_OPEN,
        public_document_id=f"RIX-{next(_seq):05d}",
        **kwargs,
    )


@pytest.mark.django_db
def test_reindex_makes_author_findable_by_fts(public_collection):
    """A doc imported with a NULL vector isn't FTS-findable by author until reindex."""
    doc = _doc(public_collection, "Cassava trials")
    doc.authors.add(Author.objects.create(first_name="Miriam", last_name="Nakato"))
    # Simulate the imported corpus: vector never built.
    Document.objects.filter(pk=doc.pk).update(search_vector=None)

    # Full-text query on the surname misses before reindex.
    assert doc not in search_documents(query="Nakato")

    call_command("reindex_repository_search")

    # …and hits afterwards.
    assert doc in search_documents(query="Nakato")


@pytest.mark.django_db
def test_reindex_collection_scope(public_collection):
    """--collection only reindexes the named collection's documents."""
    from apps.repository.documents.models import Collection

    other, _ = Collection.objects.update_or_create(
        slug="papers",
        defaults={"name": "Papers", "visibility": Collection.Visibility.PUBLIC_OPEN},
    )
    d_in = _doc(public_collection, "In scope")
    d_in.authors.add(Author.objects.create(first_name="Sam", last_name="Wabwire"))
    d_out = _doc(other, "Out of scope")
    d_out.authors.add(Author.objects.create(first_name="Sam", last_name="Wabwire"))
    Document.objects.update(search_vector=None)

    call_command("reindex_repository_search", "--collection", "theses")

    # Both are public, so FTS findability (not raw vector reads) proves which
    # one got reindexed: the in-scope doc is now findable by author surname,
    # the out-of-scope doc still has a NULL vector and isn't.
    found = list(search_documents(query="Wabwire"))
    assert d_in in found
    assert d_out not in found


@pytest.mark.django_db
def test_reindex_missing_only(public_collection):
    from apps.repository.search.indexes import update_search_vector

    indexed = _doc(public_collection, "Already indexed")
    update_search_vector(indexed.pk)
    missing = _doc(public_collection, "Never indexed")
    missing.authors.add(Author.objects.create(first_name="Iryn", last_name="Tushabe"))
    Document.objects.filter(pk=missing.pk).update(search_vector=None)

    # Should run without error and reindex the NULL-vector row into findability.
    call_command("reindex_repository_search", "--missing-only")
    assert missing in search_documents(query="Tushabe")
