from __future__ import annotations

from unittest.mock import AsyncMock, MagicMock

import pytest

from app.infrastructure.es_client import ESClient


@pytest.mark.asyncio
async def test_search_service_guides_uses_union_anchor_filter_for_doc_ids_and_matter_ids() -> None:
    raw = MagicMock()
    raw.search = AsyncMock(return_value={"hits": {"hits": []}})

    client = ESClient(raw)

    await client.search_service_guides(
        acl_filter={"term": {"acl_ids": "D_01"}},
        query_text="建设用地审批收费",
        doc_ids=["doc-1"],
        matter_ids=["matter-1"],
        size=5,
    )

    body = raw.search.await_args.kwargs["body"]
    filter_clauses = body["query"]["bool"]["filter"]
    anchor_clause = next(
        clause["bool"]
        for clause in filter_clauses
        if isinstance(clause, dict) and isinstance(clause.get("bool"), dict) and "should" in clause["bool"]
    )

    assert anchor_clause["minimum_should_match"] == 1
    assert {tuple(item.keys())[0] for item in anchor_clause["should"]} == {"terms"}
    assert {tuple(item["terms"].keys())[0] for item in anchor_clause["should"]} == {"doc_id", "linked_matter_ids"}


@pytest.mark.asyncio
async def test_delete_document_inner_still_cleans_orphan_service_guides_when_meta_missing() -> None:
    raw = MagicMock()
    raw.get = AsyncMock(side_effect=RuntimeError("meta missing"))

    client = ESClient(raw)
    client.delete_service_guides_by_doc_id = AsyncMock(return_value=1)

    result = await client._delete_document_inner("doc-orphan-guide-1")

    assert result == {
        "deleted_chunks": 0,
        "deleted_meta": 0,
        "deleted_guides": 1,
    }
    client.delete_service_guides_by_doc_id.assert_awaited_once_with("doc-orphan-guide-1")