"""KnowHub 工具表集成模块

提供工具表的查询、创建、更新功能，用于与 KnowHub 知识库同步工具信息。
"""

import httpx
import logging
from typing import Any, Optional
from pydantic import BaseModel, Field

from tool_agent.config import settings

logger = logging.getLogger(__name__)


class ToolTableClient:
    """KnowHub 工具表客户端"""

    def __init__(self, api_url: str | None = None):
        self.api_url = api_url or settings.knowhub_api
        self.timeout = 60.0

    def list_all_tools(self, limit: int = 1000) -> list[dict[str, Any]]:
        """列出所有工具

        Returns:
            工具列表
        """
        try:
            resp = httpx.get(
                f"{self.api_url}/api/resource",
                params={"limit": limit},
                timeout=self.timeout
            )
            resp.raise_for_status()
            data = resp.json()

            # 提取 results 字段
            if isinstance(data, dict) and "results" in data:
                data = data["results"]

            # 过滤出工具（ID 以 tools/ 开头）
            tools = [r for r in data if isinstance(r, dict) and r.get("id", "").startswith("tools/")]
            logger.info(f"Found {len(tools)} tools in KnowHub")
            return tools

        except Exception as e:
            logger.error(f"Failed to list tools: {e}")
            return []

    def get_tool(self, tool_id: str) -> dict[str, Any] | None:
        """获取工具详情

        Args:
            tool_id: 工具 ID，格式：tools/{category}/{slug}

        Returns:
            工具详情，失败返回 None
        """
        try:
            resp = httpx.get(
                f"{self.api_url}/api/resource/{tool_id}",
                timeout=self.timeout
            )
            resp.raise_for_status()
            tool = resp.json()
            logger.info(f"Retrieved tool: {tool_id}")
            return tool

        except Exception as e:
            logger.error(f"Failed to get tool {tool_id}: {e}")
            return None

    def search_tools_by_category(self, category: str) -> list[dict[str, Any]]:
        """按分类搜索工具

        Args:
            category: 工具分类（image_gen, image_process, model, plugin, workflow, other）

        Returns:
            工具列表
        """
        all_tools = self.list_all_tools()
        tools = [
            t for t in all_tools
            if t.get("metadata", {}).get("category") == category
        ]
        logger.info(f"Found {len(tools)} tools in category '{category}'")
        return tools

    def create_tool(
        self,
        tool_id: str,
        title: str,
        category: str,
        tool_slug: str,
        status: str = "未接入",
        description: str | None = None,
        usage: str | None = None,
        scenarios: list[str] | None = None,
        **kwargs
    ) -> dict[str, Any] | None:
        """创建新工具

        Args:
            tool_id: 工具 ID，格式：tools/{category}/{slug}
            title: 工具标题
            category: 工具分类
            tool_slug: 工具短名
            status: 接入状态（未接入/已接入/测试中）
            description: 功能描述
            usage: 使用说明
            scenarios: 应用场景列表
            **kwargs: 其他 metadata 字段

        Returns:
            创建结果，失败返回 None
        """
        try:
            tool_data = {
                "id": tool_id,
                "title": title,
                "body": "",
                "content_type": "text",
                "metadata": {
                    "category": category,
                    "tool_slug": tool_slug,
                    "status": status,
                    "description": description,
                    "usage": usage,
                    "scenarios": scenarios or [],
                    "knowledge_ids": [],
                    **kwargs
                },
                "submitted_by": "tool_agent"
            }

            resp = httpx.post(
                f"{self.api_url}/api/resource",
                json=tool_data,
                timeout=self.timeout
            )
            resp.raise_for_status()
            result = resp.json()
            logger.info(f"Created tool: {tool_id}")
            return result

        except Exception as e:
            logger.error(f"Failed to create tool {tool_id}: {e}")
            return None

    def update_tool_status(self, tool_id: str, new_status: str) -> bool:
        """更新工具状态

        Args:
            tool_id: 工具 ID
            new_status: 新状态（未接入/已接入/测试中）

        Returns:
            是否成功
        """
        try:
            # 1. 获取当前工具信息
            tool = self.get_tool(tool_id)
            if not tool:
                return False

            # 2. 更新 metadata
            metadata = tool.get("metadata", {})
            metadata["status"] = new_status

            resp = httpx.patch(
                f"{self.api_url}/api/resource/{tool_id}",
                json={"metadata": metadata},
                timeout=self.timeout
            )
            resp.raise_for_status()
            logger.info(f"Updated tool {tool_id} status to '{new_status}'")
            return True

        except Exception as e:
            logger.error(f"Failed to update tool {tool_id} status: {e}")
            return False

    def add_knowledge_link(self, tool_id: str, knowledge_ids: list[str]) -> bool:
        """添加知识关联

        Args:
            tool_id: 工具 ID
            knowledge_ids: 知识 ID 列表

        Returns:
            是否成功
        """
        try:
            # 1. 获取当前工具信息
            tool = self.get_tool(tool_id)
            if not tool:
                return False

            # 2. 合并知识 ID（去重）
            metadata = tool.get("metadata", {})
            current_ids = metadata.get("knowledge_ids", [])
            updated_ids = list(set(current_ids + knowledge_ids))
            metadata["knowledge_ids"] = updated_ids

            resp = httpx.patch(
                f"{self.api_url}/api/resource/{tool_id}",
                json={"metadata": metadata},
                timeout=self.timeout
            )
            resp.raise_for_status()
            logger.info(f"Added {len(knowledge_ids)} knowledge links to tool {tool_id}")
            return True

        except Exception as e:
            logger.error(f"Failed to add knowledge links to tool {tool_id}: {e}")
            return False

    def update_toolhub_items(self, tool_id: str, toolhub_items: list[dict[str, str]]) -> bool:
        """更新工具关联的 Tool Agent 工具列表

        Args:
            tool_id: KnowHub 工具 ID，格式：tools/{category}/{slug}
            toolhub_items: Tool Agent 工具列表，每项为 {tool_id: name}

        Returns:
            是否成功
        """
        try:
            tool = self.get_tool(tool_id)
            if not tool:
                return False

            metadata = tool.get("metadata", {})
            metadata["toolhub_items"] = toolhub_items

            resp = httpx.patch(
                f"{self.api_url}/api/resource/{tool_id}",
                json={"metadata": metadata},
                timeout=self.timeout
            )
            resp.raise_for_status()
            logger.info(f"Updated toolhub_items for {tool_id}: {len(toolhub_items)} items")
            return True

        except Exception as e:
            logger.error(f"Failed to update toolhub_items for {tool_id}: {e}")
            return False

    def sync_tool_from_registry(
        self,
        tool_id: str,
        name: str,
        category: str,
        description: str,
        backend_runtime: str
    ) -> bool:
        """从 Tool Agent Registry 同步工具到 KnowHub

        Args:
            tool_id: 工具 ID（Tool Agent 中的 tool_id）
            name: 工具名称
            category: 工具分类
            description: 工具描述
            backend_runtime: 后端运行时（local/docker/remote）

        Returns:
            是否成功
        """
        knowhub_tool_id = f"tools/{category}/{tool_id}"

        # 检查工具是否已存在
        existing_tool = self.get_tool(knowhub_tool_id)

        if existing_tool:
            # 工具已存在，更新状态为"已接入"
            logger.info(f"Tool {knowhub_tool_id} already exists, updating status")
            return self.update_tool_status(knowhub_tool_id, "已接入")
        else:
            # 创建新工具
            logger.info(f"Creating new tool {knowhub_tool_id}")
            result = self.create_tool(
                tool_id=knowhub_tool_id,
                title=name,
                category=category,
                tool_slug=tool_id,
                status="已接入",
                description=description,
                backend_runtime=backend_runtime
            )
            return result is not None


# 全局客户端实例
_client: ToolTableClient | None = None


def get_client() -> ToolTableClient:
    """获取全局 ToolTableClient 实例"""
    global _client
    if _client is None:
        _client = ToolTableClient()
    return _client
