import pytest

from metaverse.tools.databases import describe_table, list_databases, list_tables
from tests.conftest import json_response


@pytest.fixture
def db_list():
    return [
        {"id": 1, "name": "Metaverse Data", "engine": "postgres"},
        {"id": 2, "name": "Other DB", "engine": "mysql"},
    ]


@pytest.fixture
def table_metadata():
    return {
        "tables": [
            {"id": 10, "name": "customers", "schema": "public", "description": "User accounts"},
            {"id": 11, "name": "orders", "schema": "public", "description": None},
        ]
    }


@pytest.fixture
def table_query_metadata():
    return {
        "name": "customers",
        "schema": "public",
        "fields": [
            {
                "id": 1,
                "name": "id",
                "base_type": "type/Integer",
                "description": None,
                "semantic_type": "type/PK",
                "fk_target_field_id": None,
                "target": None,
            },
            {
                "id": 2,
                "name": "email",
                "base_type": "type/Text",
                "description": "User email",
                "semantic_type": None,
                "fk_target_field_id": None,
                "target": None,
            },
        ],
    }


async def test_list_databases(mock_api, db_list):
    mock_api.get("/database").mock(return_value=json_response(db_list))
    result = await list_databases()
    assert len(result) == 2
    assert result[0] == {"id": 1, "name": "Metaverse Data", "engine": "postgres"}


async def test_list_databases_wrapped_response(mock_api, db_list):
    mock_api.get("/database").mock(return_value=json_response({"data": db_list}))
    result = await list_databases()
    assert len(result) == 2


async def test_list_tables(mock_api, table_metadata):
    mock_api.get("/database/1/metadata").mock(return_value=json_response(table_metadata))
    result = await list_tables(1)
    assert len(result) == 2
    assert result[0]["name"] == "customers"
    assert result[1]["description"] == ""  # None → ""


async def test_describe_table(mock_api, table_query_metadata):
    mock_api.get("/table/10/query_metadata").mock(return_value=json_response(table_query_metadata))
    result = await describe_table(10)
    assert result["name"] == "customers"
    assert len(result["fields"]) == 2
    id_field = result["fields"][0]
    assert id_field["id"] == 1
    assert id_field["is_pk"] is True
    assert id_field["fk_target"] is None
    email_field = result["fields"][1]
    assert email_field["id"] == 2
    assert email_field["description"] == "User email"
