import pytest

from metaverse.config import settings
from metaverse.tools.queries import (
    create_question,
    execute_question,
    get_question,
    list_questions,
    run_query,
)
from tests.conftest import json_response


@pytest.fixture
def dataset_response():
    return {
        "data": {
            "cols": [{"name": "country"}, {"name": "count"}],
            "rows": [["US", 120], ["UK", 45]],
        }
    }


@pytest.fixture
def card():
    return {
        "id": 42,
        "name": "Customers by Country",
        "description": "Shows customer distribution",
        "database_id": 1,
        "dataset_query": {
            "native": {"query": "SELECT country, COUNT(*) FROM customers GROUP BY 1"}
        },
        "created_at": "2025-01-01T00:00:00Z",
    }


async def test_run_query(mock_api, dataset_response):
    mock_api.post("/dataset").mock(return_value=json_response(dataset_response))
    result = await run_query(1, "SELECT country, COUNT(*) FROM customers GROUP BY 1")
    assert result["columns"] == ["country", "count"]
    assert result["rows"] == [["US", 120], ["UK", 45]]
    assert result["row_count"] == 2
    assert result["truncated"] is False


async def test_run_query_truncated(mock_api):
    rows = [[f"row{i}"] for i in range(100)]
    mock_api.post("/dataset").mock(
        return_value=json_response({"data": {"cols": [{"name": "x"}], "rows": rows}})
    )
    result = await run_query(1, "SELECT x FROM t", limit=100)
    assert result["truncated"] is True


async def test_list_questions(mock_api, card):
    mock_api.get("/card").mock(return_value=json_response([card]))
    result = await list_questions()
    assert len(result) == 1
    assert result[0]["id"] == 42
    assert result[0]["name"] == "Customers by Country"


async def test_get_question(mock_api, card):
    mock_api.get("/card/42").mock(return_value=json_response(card))
    result = await get_question(42)
    assert result["sql"] == "SELECT country, COUNT(*) FROM customers GROUP BY 1"


async def test_create_question(mock_api, card):
    mock_api.post("/card").mock(return_value=json_response(card))
    result = await create_question("Customers by Country", 1, "SELECT country FROM customers")
    assert result["id"] == 42
    assert result["url"] == f"{settings.url}/question/42"


async def test_execute_question_list_format(mock_api):
    rows = [{"country": "US", "count": 120}, {"country": "UK", "count": 45}]
    mock_api.post("/card/42/query/json").mock(return_value=json_response(rows))
    result = await execute_question(42)
    assert result["columns"] == ["country", "count"]
    assert result["rows"][0] == ["US", 120]
