"""Saved filters tests — CRUD for reusable filter criteria."""

from __future__ import annotations

import pytest
from httpx import AsyncClient

from tests.conftest import ORIGIN_HEADER, login_client, seed_tenant_and_users


@pytest.mark.asyncio
class TestSavedFilterList:
    """GET /api/v1/saved-filters"""

    async def test_list_saved_filters_returns_200(self, client: AsyncClient, db_session):
        """GET /saved-filters returns 200 with list."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.get("/api/v1/saved-filters", headers=ORIGIN_HEADER)
        assert resp.status_code == 200
        assert isinstance(resp.json(), list)

    async def test_list_saved_filters_with_entity_type(self, client: AsyncClient, db_session):
        """GET /saved-filters?entity_type=contacts filters by entity."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.get("/api/v1/saved-filters?entity_type=contacts", headers=ORIGIN_HEADER)
        assert resp.status_code == 200
        for item in resp.json():
            assert item["entity_type"] == "contacts"

    async def test_list_saved_filters_requires_auth(self, client: AsyncClient, db_session):
        """GET /saved-filters without auth returns 401."""
        resp = await client.get("/api/v1/saved-filters", headers=ORIGIN_HEADER)
        assert resp.status_code == 401


@pytest.mark.asyncio
class TestSavedFilterCreate:
    """POST /api/v1/saved-filters"""

    async def test_create_saved_filter_returns_201(self, client: AsyncClient, db_session):
        """POST /saved-filters creates a filter and returns 201."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.post(
            "/api/v1/saved-filters",
            json={
                "name": "Important Clients",
                "entity_type": "contacts",
                "filter_criteria": {"type": "company", "search": "important"},
            },
            headers=ORIGIN_HEADER,
        )
        assert resp.status_code == 201
        data = resp.json()
        assert data["name"] == "Important Clients"
        assert data["entity_type"] == "contacts"
        assert data["filter_criteria"]["type"] == "company"

    async def test_create_saved_filter_duplicate_returns_409(self, client: AsyncClient, db_session):
        """POST /saved-filters with duplicate name returns 409."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        # Create first
        await client.post(
            "/api/v1/saved-filters",
            json={"name": "My Filter", "entity_type": "contacts", "filter_criteria": {}},
            headers=ORIGIN_HEADER,
        )
        # Create duplicate
        resp = await client.post(
            "/api/v1/saved-filters",
            json={"name": "My Filter", "entity_type": "contacts", "filter_criteria": {}},
            headers=ORIGIN_HEADER,
        )
        assert resp.status_code == 409

    async def test_create_saved_filter_invalid_entity_returns_422(self, client: AsyncClient, db_session):
        """POST /saved-filters with invalid entity_type returns 422."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.post(
            "/api/v1/saved-filters",
            json={"name": "Test", "entity_type": "invalid", "filter_criteria": {}},
            headers=ORIGIN_HEADER,
        )
        assert resp.status_code == 422


@pytest.mark.asyncio
class TestSavedFilterDelete:
    """DELETE /api/v1/saved-filters/{id}"""

    async def test_delete_saved_filter_returns_204(self, client: AsyncClient, db_session):
        """DELETE /saved-filters/{id} soft-deletes the filter."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        # Create
        create_resp = await client.post(
            "/api/v1/saved-filters",
            json={"name": "To Delete", "entity_type": "contacts", "filter_criteria": {}},
            headers=ORIGIN_HEADER,
        )
        filter_id = create_resp.json()["id"]
        # Delete
        resp = await client.delete(f"/api/v1/saved-filters/{filter_id}", headers=ORIGIN_HEADER)
        assert resp.status_code == 204
        # Verify gone from list
        list_resp = await client.get("/api/v1/saved-filters", headers=ORIGIN_HEADER)
        assert not any(f["id"] == filter_id for f in list_resp.json())

    async def test_delete_saved_filter_not_found_returns_404(self, client: AsyncClient, db_session):
        """DELETE non-existent filter returns 404."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.delete(
            "/api/v1/saved-filters/00000000-0000-0000-0000-000000000000",
            headers=ORIGIN_HEADER,
        )
        assert resp.status_code == 404

    async def test_delete_saved_filter_invalid_uuid_returns_400(self, client: AsyncClient, db_session):
        """DELETE with invalid UUID returns 400."""
        await seed_tenant_and_users(db_session)
        await login_client(client, "admin@tenanta.com")
        resp = await client.delete("/api/v1/saved-filters/not-a-uuid", headers=ORIGIN_HEADER)
        assert resp.status_code == 400
