# -*- coding: utf-8 -*-
"""
MCP 远程工具列表查询 —— 格式化输出所有可用的 MCP 工具及参数签名
"""

import asyncio
import shutil
from fastmcp import Client

# ── 终端宽度 ──
WIDTH = min(shutil.get_terminal_size().columns, 120)

# ── 工具分类定义（按名称前缀归类）──
CATEGORY_MAP = {
    "vent":   "🌬️  通风监测",
    "device": "🔧 设备管理",
    "tunnel": "🛤️  巷道信息",
    "mine":   "⛏️  煤矿基础",
    "needq":  "📊 需风量计算",
}

def _category(name: str) -> str:
    for prefix, label in CATEGORY_MAP.items():
        if name.startswith(prefix):
            return label
    return "📦 其他"


def parse_tool_params(schema: dict) -> list[dict]:
    """解析 inputSchema 为参数列表"""
    params = []
    required = schema.get("required", [])
    props = schema.get("properties", {})
    for name, info in props.items():
        params.append({
            "name": name,
            "type": info.get("type", "—"),
            "desc": (info.get("description", "") or "")[:120],
            "required": name in required,
        })
    return params


# ── 主入口 ──

MCP_URL = "http://39.97.59.228:8071/mcp"
client = Client(MCP_URL)


async def list_all_mcp_tools_tcp():
    """TCP 远程 MCP 客户端查询工具列表"""
    async with client:
        tools = await client.list_tools()

        # ══════════════════════════════════════════════
        #  头部
        # ══════════════════════════════════════════════
        print()
        print("╔" + "═" * (WIDTH - 2) + "╗")
        print("║" + f"  🔌  MCP 远程工具列表  |  {MCP_URL}  |  共 {len(tools)} 个工具".center(WIDTH - 2) + "║")
        print("╚" + "═" * (WIDTH - 2) + "╝")
        print()

        # 按类别分组
        groups: dict[str, list] = {}
        for t in tools:
            cat = _category(t.name)
            groups.setdefault(cat, []).append(t)

        order = ["🌬️  通风监测", "🛤️  巷道信息", "🔧 设备管理", "📊 需风量计算", "⛏️  煤矿基础", "📦 其他"]
        index = 0

        for cat in order:
            if cat not in groups:
                continue
            group_tools = groups[cat]
            print(f"  {cat}（{len(group_tools)} 个）")
            print(f"  {'─' * (WIDTH - 6)}")

            for t in group_tools:
                index += 1
                # ── 工具名 + 序号 ──
                print(f"\n  ┌─ [{index:02d}] {t.name} {'─' * max(WIDTH - len(t.name) - 15, 0)}")

                # ── 描述 ──
                desc = (t.description or "").strip()
                if desc:
                    # 自动换行
                    for line in _wrap(desc, WIDTH - 8):
                        print(f"  │  📝 {line}")

                # ── 参数表 ──
                params = parse_tool_params(t.inputSchema)
                if params:
                    print(f"  │  ┌ 参数{'─' * (WIDTH - 13)}")
                    for p in params:
                        flag = "🔴" if p["required"] else "🟢"
                        print(f"  │  │ {flag} {p['name']}: {p['type']}")
                        if p["desc"]:
                            for line in _wrap(p["desc"], WIDTH - 12):
                                print(f"  │  │    {line}")
                    print(f"  │  └{'─' * (WIDTH - 9)}")
                else:
                    print(f"  │  (无参数)")

                print(f"  └{'─' * (WIDTH - 6)}")

            print()

        # ══════════════════════════════════════════════
        #  底部统计
        # ══════════════════════════════════════════════
        total_params = sum(
            len(parse_tool_params(t.inputSchema)) for t in tools
        )
        print("╔" + "═" * (WIDTH - 2) + "╗")
        print("║" + f"  ✅ 总计 {len(tools)} 个工具，{total_params} 个参数，{len(groups)} 个分类".ljust(WIDTH - 2) + "║")
        print("╚" + "═" * (WIDTH - 2) + "╝")
        print()


def _wrap(text: str, width: int) -> list[str]:
    """按宽度自动换行，尊重中文宽度"""
    lines = []
    while len(text) > width:
        # 尝试在空格处断行
        cut = text.rfind(" ", 0, width)
        if cut == -1:
            cut = width
        lines.append(text[:cut].strip())
        text = text[cut:].strip()
    if text:
        lines.append(text)
    return lines


asyncio.run(list_all_mcp_tools_tcp())
