"""GDB catalog tools — list, delete, move."""

from __future__ import annotations

from typing import Any

from mcp.types import ToolAnnotations

from mcp_eregistrations_gdb.gdb_client import GDBClient, GDBClientError, translate_error
from mcp_eregistrations_gdb.server import mcp


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def gdb_catalog_list(instance: str | None = None) -> dict[str, Any]:
    """List all database catalogs with their databases.

    Args:
        instance: Instance name (default: auto-select).

    Returns:
        dict with count, catalogs (each with databases array).
    """
    try:
        async with GDBClient.for_instance(instance) as client:
            data = await client.get("/databases")
            if not isinstance(data, list):
                data = data.get("catalogs", [])
            catalogs = []
            for cat in data:
                catalogs.append(
                    {
                        "id": cat.get("id"),
                        "code": cat.get("code"),
                        "name": cat.get("name"),
                        "order": cat.get("order"),
                        "group_id": cat.get("group_id"),
                        "database_count": len(cat.get("databases", [])),
                        "databases": [
                            {
                                "id": db.get("id"),
                                "version": db.get("version"),
                                "is_draft": db.get("is_draft"),
                            }
                            for db in cat.get("databases", [])
                        ],
                    }
                )
            return {"count": len(catalogs), "catalogs": catalogs}
    except GDBClientError as e:
        raise translate_error(e, resource_type="catalog") from e


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=False))
async def gdb_catalog_delete(
    catalog_id: int,
    instance: str | None = None,
) -> dict[str, Any]:
    """Delete a database catalog by ID.

    Args:
        catalog_id: Integer ID of the catalog to delete.
        instance: Instance name (default: auto-select).

    Returns:
        dict with deleted (bool), catalog_id.
    """
    try:
        async with GDBClient.for_instance(instance) as client:
            await client.delete(f"/api/v1/database-catalog/{catalog_id}")
            return {"deleted": True, "catalog_id": catalog_id}
    except GDBClientError as e:
        raise translate_error(e, resource_type="catalog", resource_id=catalog_id) from e


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=False))
async def gdb_catalog_move(
    catalog_id: int,
    index: int,
    group_id: int | None = None,
    instance: str | None = None,
) -> dict[str, Any]:
    """Move a catalog to a new position (and optionally into a group).

    Args:
        catalog_id: Integer ID of the catalog to move.
        index: Target position index.
        group_id: Target group ID, or null for ungrouped (default: None).
        instance: Instance name (default: auto-select).

    Returns:
        dict with moved (bool), catalog_id, index, group_id.
    """
    try:
        async with GDBClient.for_instance(instance) as client:
            body: dict[str, Any] = {"index": index, "group_id": group_id}
            await client.post(f"/api/v1/database-catalog/{catalog_id}/move", data=body)
            return {
                "moved": True,
                "catalog_id": catalog_id,
                "index": index,
                "group_id": group_id,
            }
    except GDBClientError as e:
        raise translate_error(e, resource_type="catalog", resource_id=catalog_id) from e
