"""
技能与工具管理工具 (工具 24-29)
"""

import json

from ._base import register_tool, ToolDef


@register_tool("get_skill_by_datasource")
class GetSkillByDatasourceTool(ToolDef):
    name = "get_skill_by_datasource"
    description = "根据数据源获取技能信息"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.get(f"/datasource/skill/getByDatasource/{args['datasourceId']}")


@register_tool("get_skill_tools")
class GetSkillToolsTool(ToolDef):
    name = "get_skill_tools"
    description = "获取技能下的工具列表"
    input_schema = {
        "type": "object",
        "properties": {
            "skillId": {"type": "string", "description": "技能 ID"},
        },
        "required": ["skillId"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.get(f"/datasource/skill/getBySkillId/{args['skillId']}")


@register_tool("create_skill")
class CreateSkillTool(ToolDef):
    name = "create_skill"
    description = "为数据源创建技能"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
            "name": {"type": "string", "description": "技能名称（不传则自动生成）"},
            "description": {"type": "string", "description": "技能描述"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.post("/datasource/skill/createOrGet", json_data=args)


@register_tool("create_sql_tool")
class CreateSqlToolTool(ToolDef):
    name = "create_sql_tool"
    description = "将 SQL 查询创建为可复用工具（支持批量）"
    input_schema = {
        "type": "object",
        "properties": {
            "skillId": {"type": "string", "description": "技能 ID"},
            "tableIds": {
                "type": "array",
                "description": "关联的表 ID 数组",
                "items": {"type": "string"},
            },
            "suggestions": {
                "type": "array",
                "description": "SQL 工具建议数组",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string", "description": "工具名称"},
                        "businessDescription": {"type": "string", "description": "业务描述"},
                        "sqlTemplate": {"type": "string", "description": "SQL 模板（支持 #{param} 参数占位）"},
                        "sqlParams": {"type": "string", "description": "参数 JSON Schema（JSON 字符串或对象）"},
                        "resultType": {"type": "string", "enum": ["single", "list"], "default": "list", "description": "结果类型，默认 list"},
                        "businessScenario": {"type": "string", "description": "业务场景描述"},
                    },
                    "required": ["name", "businessDescription", "sqlTemplate"],
                },
            },
        },
        "required": ["skillId", "suggestions"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        # 处理 suggestions 中的 sqlParams
        if "suggestions" in args and isinstance(args["suggestions"], list):
            for suggestion in args["suggestions"]:
                if "sqlParams" in suggestion and isinstance(suggestion["sqlParams"], dict):
                    suggestion["sqlParams"] = json.dumps(suggestion["sqlParams"])
        return await self.client.post("/datasource/skill/confirmTools", json_data=args)


@register_tool("delete_skill_tool")
class DeleteSkillToolTool(ToolDef):
    name = "delete_skill_tool"
    description = "删除技能下的工具"
    input_schema = {
        "type": "object",
        "properties": {
            "skillToolId": {"type": "string", "description": "工具 ID"},
        },
        "required": ["skillToolId"],
    }

    async def execute(self, args: dict) -> dict:
        return await self.client.delete(f"/datasource/skill/tskilltool/{args['skillToolId']}")


@register_tool("update_skill_config")
class UpdateSkillConfigTool(ToolDef):
    name = "update_skill_config"
    description = "更新技能（名称/描述/MCP 配置模板等）。对应后端 skill/updateOrGet"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
            "skillId": {"type": "string", "description": "技能 ID（可选）"},
            "name": {"type": "string", "description": "技能名称（可选）"},
            "description": {"type": "string", "description": "技能描述（可选）"},
            "configTemplate": {"type": "string", "description": "配置模板 JSON 字符串（可选）"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        # 如果 configTemplate 是 dict，转为 JSON 字符串
        if "configTemplate" in args and isinstance(args["configTemplate"], dict):
            args["configTemplate"] = json.dumps(args["configTemplate"])
        return await self.client.post("/datasource/skill/updateOrGet", json_data=args)


@register_tool("update_skill_tool")
class UpdateSkillToolTool(ToolDef):
    name = "update_skill_tool"
    description = "修改技能下某个工具的名称/描述/SQL等（对应后端 tskilltool/updateOrGet，upsert 语义）"
    # 真实工具实体字段（已真机探测确认）：主键 id、展示名 uniqueName、描述 description、
    # SQL 模板 sqlTemplate、结果类型 resultType。后端不认 skillToolId/businessDescription/businessScenario。
    input_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "string", "description": "技能工具 ID（get_skill_tools 返回的 id）"},
            "uniqueName": {"type": "string", "description": "工具展示名（可选）"},
            "description": {"type": "string", "description": "工具描述（可选）"},
            "sqlTemplate": {"type": "string", "description": "SQL 模板（可选）"},
            "resultType": {"type": "string", "enum": ["single", "list"], "description": "结果类型（可选）"},
        },
        "required": ["id"],
    }

    # 旧参数名 -> 真实字段名（向后兼容此前错误实现的调用方）
    _LEGACY_MAP = {
        "skillToolId": "id",
        "name": "uniqueName",
        "businessDescription": "description",
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        for old, new in self._LEGACY_MAP.items():
            if old in args and new not in args:
                args[new] = args.pop(old)
            else:
                args.pop(old, None)
        # businessScenario 后端实体无此字段，丢弃避免干扰
        args.pop("businessScenario", None)
        return await self.client.post("/datasource/skill/tskilltool/updateOrGet", json_data=args)
