"""Tests for the Admin API endpoints."""

import pytest
from httpx import AsyncClient
from unittest.mock import AsyncMock


@pytest.mark.asyncio
class TestAdminStats:
    """GET /api/v1/admin/stats — system dashboard statistics."""

    async def test_stats_requires_auth(self, client: AsyncClient, api_prefix: str):
        """Admin stats should reject unauthenticated requests."""
        resp = await client.get(f"{api_prefix}/admin/stats")
        assert resp.status_code in (401, 403)

    async def test_stats_returns_200(self, client: AsyncClient, api_prefix: str, auth_headers: dict):
        resp = await client.get(f"{api_prefix}/admin/stats", headers=auth_headers)
        assert resp.status_code == 200
        body = resp.json()
        # Should include ES, Neo4j and Redis status
        assert "total_documents" in body or "es_status" in body

    async def test_stats_contains_service_health(self, client: AsyncClient, api_prefix: str, auth_headers: dict):
        resp = await client.get(f"{api_prefix}/admin/stats", headers=auth_headers)
        body = resp.json()
        # All three services should have a status indicator
        for key in ("es_status", "neo4j_status", "redis_status"):
            assert key in body, f"Missing {key} in admin stats"


@pytest.mark.asyncio
class TestAdminIngestLogs:
    """GET /api/v1/admin/ingest-logs — paginated ingestion logs."""

    async def test_ingest_logs_requires_auth(self, client: AsyncClient, api_prefix: str):
        resp = await client.get(f"{api_prefix}/admin/ingest-logs")
        assert resp.status_code in (401, 403)

    async def test_ingest_logs_returns_200(self, client: AsyncClient, api_prefix: str, auth_headers: dict):
        resp = await client.get(f"{api_prefix}/admin/ingest-logs", headers=auth_headers)
        assert resp.status_code == 200
        body = resp.json()
        assert "total" in body
        assert "records" in body
        assert isinstance(body["records"], list)

    async def test_ingest_logs_pagination(self, client: AsyncClient, api_prefix: str, auth_headers: dict):
        resp = await client.get(f"{api_prefix}/admin/ingest-logs", params={
            "page": 1,
            "page_size": 5,
        }, headers=auth_headers)
        assert resp.status_code == 200
        body = resp.json()
        assert len(body["records"]) <= 5


@pytest.mark.asyncio
class TestAdminDeleteDocument:
    """DELETE /api/v1/admin/document/{doc_id} — admin document deletion."""

    async def test_delete_requires_auth(self, client: AsyncClient, api_prefix: str):
        resp = await client.delete(f"{api_prefix}/admin/document/nonexistent_doc_id_12345")
        assert resp.status_code in (401, 403)

    async def test_delete_nonexistent_doc(self, client: AsyncClient, api_prefix: str, auth_headers: dict):
        resp = await client.delete(
            f"{api_prefix}/admin/document/nonexistent_doc_id_12345",
            headers=auth_headers,
        )
        # Should return 404 when doc doesn't exist
        assert resp.status_code == 404

    async def test_delete_returns_success_when_only_service_guide_was_deleted(
        self,
        client: AsyncClient,
        api_prefix: str,
        auth_headers: dict,
    ):
        client.app.state.es_client.delete_document = AsyncMock(
            return_value={
                "deleted_chunks": 0,
                "deleted_meta": 0,
                "deleted_guides": 1,
            }
        )
        client.app.state.neo4j_client.delete_document_graph = AsyncMock(
            return_value={"deleted_nodes": 0}
        )

        resp = await client.delete(
            f"{api_prefix}/admin/document/orphan-guide-doc-1",
            headers=auth_headers,
        )

        assert resp.status_code == 200
        body = resp.json()
        assert body["doc_id"] == "orphan-guide-doc-1"
        assert body["deleted_guides"] == 1
        assert body["deleted_meta"] is False
        assert body["deleted_chunks"] == 0
