"""Tests for the geographic + subject facets added for legacy-site parity.

Covers the new ``search_documents`` filters (region / country / subject /
publisher / conference) and that those terms are folded into ``search_vector``.
"""

from __future__ import annotations

import itertools

import pytest
from django.urls import reverse

from apps.repository.documents.models import Document, Keyword, Region
from apps.repository.search.indexes import update_search_vector
from apps.repository.search.services import search_documents


_pub_seq = itertools.count(1)


def _published(collection, title, **kwargs):
    # public_document_id is unique and normally allocated by the service layer;
    # direct create() leaves it '', so stamp a unique value per test doc.
    doc = Document.objects.create(
        title=title,
        collection=collection,
        status=Document.Status.PUBLISHED,
        visibility=Document.Visibility.PUBLIC_OPEN,
        public_document_id=f"TEST-{next(_pub_seq):05d}",
        **kwargs,
    )
    return doc


@pytest.mark.django_db
def test_regions_seeded_by_migration():
    # 0011_seed_regions installs the 12 controlled regions.
    assert Region.objects.filter(slug="east-africa").exists()
    assert Region.objects.count() >= 12


@pytest.mark.django_db
def test_filter_by_region(public_collection):
    ea = Region.objects.get(slug="east-africa")
    sa = Region.objects.get(slug="southern-africa")
    d1 = _published(public_collection, "Maize in Uganda")
    d1.regions.add(ea)
    d2 = _published(public_collection, "Wheat in Lesotho")
    d2.regions.add(sa)

    results = search_documents(filters={"region": "east-africa"})
    assert d1 in results
    assert d2 not in results


@pytest.mark.django_db
def test_filter_by_country(public_collection):
    d1 = _published(public_collection, "Coffee study", country="Uganda")
    _published(public_collection, "Tea study", country="Kenya")

    results = search_documents(filters={"country": "Uganda"})
    assert [d.pk for d in results] == [d1.pk]


@pytest.mark.django_db
def test_filter_by_subject_keyword(public_collection):
    kw = Keyword.objects.create(
        label="Agricultural research",
        slug="agricultural-research",
        kind=Keyword.Kind.AGRIS_CATEGORY,
    )
    d1 = _published(public_collection, "On research systems")
    d1.keywords.add(kw)
    _published(public_collection, "Unrelated doc")

    results = search_documents(filters={"subject": "agricultural-research"})
    assert [d.pk for d in results] == [d1.pk]


@pytest.mark.django_db
def test_filter_by_publisher_and_conference(public_collection):
    d1 = _published(public_collection, "Proceedings paper",
                    publisher="RUFORUM", conference_name="RUFORUM Biennial 2021")
    _published(public_collection, "Other", publisher="Elsevier")

    assert [d.pk for d in search_documents(filters={"publisher": "RUFORUM"})] == [d1.pk]
    assert [d.pk for d in search_documents(
        filters={"conference": "RUFORUM Biennial 2021"})] == [d1.pk]


@pytest.mark.django_db
def test_browse_by_region_page_lists_tagged_regions(client, public_collection):
    ea = Region.objects.get(slug="east-africa")
    d = _published(public_collection, "Regional study")
    d.regions.add(ea)

    resp = client.get(reverse("repo_documents:browse_regions"))
    assert resp.status_code == 200
    body = resp.content.decode()
    assert "Browse by region" in body
    assert "East Africa" in body
    # Row links into the pre-filtered browse surface.
    assert "?region=east-africa" in body


@pytest.mark.django_db
def test_browse_by_country_and_subject_pages_render(client, public_collection):
    kw = Keyword.objects.create(
        label="Agricultural research", slug="agricultural-research",
        kind=Keyword.Kind.AGRIS_CATEGORY,
    )
    d = _published(public_collection, "Coffee", country="Uganda")
    d.keywords.add(kw)

    rc = client.get(reverse("repo_documents:browse_countries"))
    assert rc.status_code == 200 and "Uganda" in rc.content.decode()

    rs = client.get(reverse("repo_documents:browse_subjects"))
    body = rs.content.decode()
    assert rs.status_code == 200
    assert "AGRIS subject categories" in body and "Agricultural research" in body


@pytest.mark.django_db
def test_browse_page_shows_geo_facets_and_nav(client, public_collection):
    ea = Region.objects.get(slug="east-africa")
    d = _published(public_collection, "Doc", country="Kenya")
    d.regions.add(ea)

    resp = client.get(reverse("repo_documents:browse"))
    body = resp.content.decode()
    assert resp.status_code == 200
    # Browse-by nav rail rendered.
    assert reverse("repo_documents:browse_regions") in body
    # Geographic facet fieldsets surface when there is matching data.
    assert "East Africa" in body and "Kenya" in body


@pytest.mark.django_db
def test_search_vector_includes_country_region_and_keywords(public_collection):
    region = Region.objects.get(slug="east-africa")
    kw = Keyword.objects.create(label="cassava", slug="cassava")
    doc = _published(public_collection, "A study", country="Rwanda")
    doc.regions.add(region)
    doc.keywords.add(kw)

    assert update_search_vector(doc.pk) is True

    # Each folded term is now findable by full-text search.
    for term in ("Rwanda", "East Africa", "cassava"):
        assert doc in search_documents(query=term), f"{term!r} not in vector"
