# #region Test.SupersetClient.DashboardsList [C:3] [TYPE Module] [SEMANTICS test,superset,dashboard,list]
# @BRIEF Unit tests for dashboard listing mixin — paginated list, summary projection.
# @RELATION BINDS_TO -> [SupersetDashboardsListMixin]
# @TEST_EDGE: empty_dashboards -> get_dashboards returns (0, [])
from unittest.mock import AsyncMock, MagicMock

import pytest

from src.core.config_models import Environment
from src.core.superset_client import SupersetClient


def _make_client() -> SupersetClient:
    env = Environment(id="env1", name="T", url="http://test.local", username="u", password="p")
    client = SupersetClient(env)
    mc = MagicMock()
    mc.request = AsyncMock(return_value={})
    mc.fetch_paginated_data = AsyncMock(return_value=[])
    client.client = mc
    client.network = mc
    return client


# ── get_dashboards ──────────────────────────────────────────────────────────

# #region test_get_dashboards_success [C:2] [TYPE Function]
# @BRIEF get_dashboards returns (count, data) from paginated fetch.
@pytest.mark.asyncio
async def test_get_dashboards_success():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[{"id": 1}, {"id": 2}, {"id": 3}])
    count, data = await client.get_dashboards()
    assert count == 3
    assert len(data) == 3
# #endregion test_get_dashboards_success

# #region test_get_dashboards_empty [C:2] [TYPE Function]
# @BRIEF get_dashboards returns (0, []) when no dashboards exist.
@pytest.mark.asyncio
async def test_get_dashboards_empty():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[])
    count, data = await client.get_dashboards()
    assert count == 0
    assert data == []
# #endregion test_get_dashboards_empty

# #region test_get_dashboards_with_query [C:2] [TYPE Function]
# @BRIEF get_dashboards passes custom query columns through.
@pytest.mark.asyncio
async def test_get_dashboards_with_query():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[{"id": 1}])
    await client.get_dashboards(query={"columns": ["id", "slug"]})
    call_kwargs = client.client.fetch_paginated_data.call_args
    base_query = call_kwargs.kwargs["pagination_options"]["base_query"]
    assert base_query["columns"] == ["id", "slug"]
# #endregion test_get_dashboards_with_query

# ── get_dashboards_page ─────────────────────────────────────────────────────

# #region test_get_dashboards_page [C:2] [TYPE Function]
# @BRIEF get_dashboards_page returns (count, result) from single API call.
@pytest.mark.asyncio
async def test_get_dashboards_page():
    client = _make_client()
    client.client.request = AsyncMock(return_value={"result": [{"id": 1}], "count": 50})
    total, data = await client.get_dashboards_page()
    assert total == 50
    assert len(data) == 1
# #endregion test_get_dashboards_page

# #region test_get_dashboards_page_no_count [C:2] [TYPE Function]
# @BRIEF get_dashboards_page falls back to len(result) when count is absent.
@pytest.mark.asyncio
async def test_get_dashboards_page_no_count():
    client = _make_client()
    client.client.request = AsyncMock(return_value={"result": [{"id": 1}, {"id": 2}]})
    total, data = await client.get_dashboards_page()
    assert total == 2
# #endregion test_get_dashboards_page_no_count

# ── get_dashboards_summary ──────────────────────────────────────────────────

# #region test_get_dashboards_summary [C:2] [TYPE Function]
# @BRIEF get_dashboards_summary projects owner/creator fields correctly.
@pytest.mark.asyncio
async def test_get_dashboards_summary():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[{
        "id": 1, "slug": "s1", "dashboard_title": "T1", "url": "/u",
        "changed_on_utc": "2025-01-01", "published": True,
        "owners": [{"username": "alice", "first_name": "Alice", "last_name": "A"}],
        "created_by": {"username": "bob"}, "changed_by": {"username": "carol"},
        "changed_by_name": "Carol",
    }])
    result = await client.get_dashboards_summary()
    assert len(result) == 1
    assert result[0]["status"] == "published"
    assert result[0]["owners"] == ["Alice A"]
# #endregion test_get_dashboards_summary

# #region test_get_dashboards_summary_draft [C:2] [TYPE Function]
# @BRIEF get_dashboards_summary marks unpublished dashboards as 'draft'.
@pytest.mark.asyncio
async def test_get_dashboards_summary_draft():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[{
        "id": 2, "slug": "s2", "dashboard_title": "Draft", "published": False,
        "owners": None, "created_by": None, "changed_by": None, "changed_by_name": None,
    }])
    result = await client.get_dashboards_summary()
    assert result[0]["status"] == "draft"
# #endregion test_get_dashboards_summary_draft

# #region test_get_dashboards_summary_require_slug [C:2] [TYPE Function]
# @BRIEF get_dashboards_summary adds slug filter when require_slug=True.
@pytest.mark.asyncio
async def test_get_dashboards_summary_require_slug():
    client = _make_client()
    client.client.fetch_paginated_data = AsyncMock(return_value=[])
    await client.get_dashboards_summary(require_slug=True)
    call_kwargs = client.client.fetch_paginated_data.call_args
    base_query = call_kwargs.kwargs["pagination_options"]["base_query"]
    assert any(f["col"] == "slug" for f in base_query.get("filters", []))
# #endregion test_get_dashboards_summary_require_slug

# ── get_dashboards_summary_page ─────────────────────────────────────────────

# #region test_get_dashboards_summary_page [C:2] [TYPE Function]
# @BRIEF get_dashboards_summary_page returns projected page with search filter.
@pytest.mark.asyncio
async def test_get_dashboards_summary_page():
    client = _make_client()
    client.client.request = AsyncMock(return_value={
        "result": [{"id": 1, "slug": "s", "dashboard_title": "Sales", "published": True,
                     "owners": [{"username": "admin"}], "created_by": None, "changed_by": None, "changed_by_name": None}],
        "count": 1,
    })
    total, data = await client.get_dashboards_summary_page(page=1, page_size=20, search="Sales")
    assert total == 1
    assert data[0]["title"] == "Sales"
# #endregion test_get_dashboards_summary_page

# #region test_get_dashboards_summary_page_no_search [C:2] [TYPE Function]
# @BRIEF get_dashboards_summary_page works without search term.
@pytest.mark.asyncio
async def test_get_dashboards_summary_page_no_search():
    client = _make_client()
    client.client.request = AsyncMock(return_value={"result": [], "count": 0})
    total, data = await client.get_dashboards_summary_page(page=1, page_size=10)
    assert total == 0
    assert data == []
# #endregion test_get_dashboards_summary_page_no_search

# #endregion Test.SupersetClient.DashboardsList
