"""MCP resources — expose Metabase schema as readable URIs.

Clients read these instead of chaining list_databases → list_tables → describe_table calls.

URIs:
  metaverse://schema                    — full schema: all databases + every table + all fields
  metaverse://database/{database_id}    — one database: all tables + fields
  metaverse://table/{table_id}          — one table: all fields with types and relationships
"""

from metaverse.app import mcp
from metaverse.client import get as api_get


def _field_line(f: dict) -> str:
    parts = [f["name"], f.get("base_type", "")]
    if f.get("semantic_type") == "type/PK":
        parts.append("PK")
    if f.get("fk_target_field_id") and f.get("target"):
        target = f["target"]
        table = (target.get("table") or {}).get("name", "?")
        field = target.get("name", "?")
        parts.append(f"FK → {table}.{field}")
    if f.get("description"):
        parts.append(f.get("description", ""))
    return "- " + "  |  ".join(p for p in parts if p)


def _table_block(table_id: int, table_name: str, fields: list[dict]) -> str:
    lines = [f"### {table_name}"]
    for f in fields:
        lines.append(_field_line(f))
    return "\n".join(lines)


@mcp.resource("metaverse://schema")
async def full_schema() -> str:
    """Complete schema for all connected databases.

    Returns every database, every table, and every field in a single markdown document.
    Read this once at the start of a session to understand all available data — no further
    schema tool calls needed.
    """
    databases = await api_get("/database")
    db_list = databases if isinstance(databases, list) else databases.get("data", [])

    sections: list[str] = ["# Metaverse Schema\n"]

    for db in db_list:
        sections.append(f"## Database: {db['name']}  (id: {db['id']}, engine: {db.get('engine', '?')})\n")
        meta = await api_get(f"/database/{db['id']}/metadata")
        for table in meta.get("tables", []):
            detail = await api_get(f"/table/{table['id']}/query_metadata")
            sections.append(_table_block(table["id"], table["name"], detail.get("fields", [])))
            sections.append("")

    return "\n".join(sections)


@mcp.resource("metaverse://database/{database_id}")
async def database_schema(database_id: int) -> str:
    """Schema for a single database: all tables and their fields.

    Use when you already know the database_id and want its full structure without
    fetching the entire multi-database schema.
    """
    meta = await api_get(f"/database/{database_id}/metadata")
    db_name = meta.get("name", f"Database {database_id}")

    sections = [f"# {db_name}  (id: {database_id})\n"]
    for table in meta.get("tables", []):
        detail = await api_get(f"/table/{table['id']}/query_metadata")
        sections.append(_table_block(table["id"], table["name"], detail.get("fields", [])))
        sections.append("")

    return "\n".join(sections)


@mcp.resource("metaverse://table/{table_id}")
async def table_schema(table_id: int) -> str:
    """Schema for a single table: all fields with types, PK/FK relationships, and descriptions.

    Use when you already know the table_id and only need one table's structure.
    """
    data = await api_get(f"/table/{table_id}/query_metadata")
    table_name = data.get("name", f"Table {table_id}")
    schema = data.get("schema", "public")

    lines = [
        f"# {table_name}  (id: {table_id}, schema: {schema})",
        "",
    ]
    for f in data.get("fields", []):
        lines.append(_field_line(f))

    return "\n".join(lines)
