"""
数据库与表管理工具 (工具 7-12)
"""

from ._base import register_tool, ToolDef


@register_tool("list_databases")
class ListDatabasesTool(ToolDef):
    name = "list_databases"
    description = "获取指定数据源下的数据库列表"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
            "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"},
            "pageNum": {"type": "integer", "default": 1, "description": "页码"},
            "pageSize": {"type": "integer", "default": 20, "description": "每页数量"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        params = {k: v for k, v in args.items() if v is not None}
        return await self.client.get("/datasource/config/list", params=params)


@register_tool("list_tables")
class ListTablesTool(ToolDef):
    name = "list_tables"
    description = "获取指定数据源下的表列表"
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "数据源 ID"},
            "sourceType": {"type": "string", "enum": ["builtin", "external"], "description": "数据源类型"},
            "pageNum": {"type": "integer", "default": 1, "description": "页码"},
            "pageSize": {"type": "integer", "default": 20, "description": "每页数量"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        params = {k: v for k, v in args.items() if v is not None}
        return await self.client.get("/datasource/table/list", params=params)


@register_tool("list_tables_with_ai")
class ListTablesWithAiTool(ToolDef):
    name = "list_tables_with_ai"
    description = (
        "获取表元数据列表（含 AI 训练描述），内置库管理的主列表。"
        "注意：datasourceId 实为「配置/库」ID（即 create_connection_config 落库后的 config id）"
    )
    input_schema = {
        "type": "object",
        "properties": {
            "datasourceId": {"type": "string", "description": "配置/库 ID（非数据源连接 ID）"},
            "pageNum": {"type": "integer", "default": 1, "description": "页码"},
            "pageSize": {"type": "integer", "default": 20, "description": "每页数量"},
        },
        "required": ["datasourceId"],
    }

    async def execute(self, args: dict) -> dict:
        params = {k: v for k, v in args.items() if v is not None}
        return await self.client.get("/datasource/table/ailist", params=params)


@register_tool("get_table_detail")
class GetTableDetailTool(ToolDef):
    name = "get_table_detail"
    description = "获取表的完整结构信息（字段列表、主键、类型等）"
    input_schema = {
        "type": "object",
        "properties": {
            "tableId": {"type": "string", "description": "表 ID"},
        },
        "required": ["tableId"],
    }

    async def execute(self, args: dict) -> dict:
        table_id = args["tableId"]
        return await self.client.get(f"/datasource/table/{table_id}/detail")


@register_tool("create_table")
class CreateTableTool(ToolDef):
    name = "create_table"
    description = "在指定数据库创建新表"
    input_schema = {
        "type": "object",
        "properties": {
            "connectionId": {"type": "string", "description": "数据源连接 ID"},
            "databaseName": {"type": "string", "description": "目标数据库名"},
            "tableName": {"type": "string", "description": "表名（小写字母+数字+下划线）"},
            "tableComment": {"type": "string", "description": "表注释"},
            "columns": {
                "type": "array",
                "description": "字段定义数组",
                "items": {
                    "type": "object",
                    "properties": {
                        "columnName": {"type": "string", "description": "字段名"},
                        "columnType": {"type": "string", "description": "字段类型（VARCHAR/INTEGER/SERIAL等）"},
                        "columnLength": {"type": "integer", "description": "字段长度"},
                        "isPrimaryKey": {"type": "boolean", "description": "是否主键"},
                        "isNullable": {"type": "boolean", "description": "是否可空"},
                        "isAutoIncrement": {"type": "boolean", "description": "是否自增"},
                        "columnComment": {"type": "string", "description": "字段注释"},
                        "defaultValue": {"type": "string", "description": "默认值"},
                    },
                    "required": ["columnName", "columnType"],
                },
            },
        },
        "required": ["connectionId", "databaseName", "tableName", "columns"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        connection_id = args.pop("connectionId")
        return await self.client.post(f"/datasource/connection/{connection_id}/create_table", json_data=args)


@register_tool("alter_table")
class AlterTableTool(ToolDef):
    name = "alter_table"
    description = "修改已有表结构（增/改/删字段）"
    input_schema = {
        "type": "object",
        "properties": {
            "connectionId": {"type": "string", "description": "数据源连接 ID"},
            "databaseName": {"type": "string", "description": "数据库名"},
            "tableName": {"type": "string", "description": "表名"},
            "operations": {
                "type": "array",
                "description": "表结构变更操作数组",
                "items": {
                    "type": "object",
                    "properties": {
                        "operation": {"type": "string", "enum": ["ADD_COLUMN", "MODIFY_COLUMN", "DROP_COLUMN"], "description": "变更类型：新增/修改/删除字段（后端实测仅支持这三种）"},
                        "column": {"type": "object", "description": "列定义。ADD/MODIFY 需 columnName+columnType(+columnLength/columnComment 等)；DROP 仅需 columnName"},
                    },
                    "required": ["operation", "column"],
                },
            },
            "tableComment": {"type": "string", "description": "表注释"},
        },
        "required": ["connectionId", "databaseName", "tableName", "operations"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        connection_id = args.pop("connectionId")
        return await self.client.put(f"/datasource/connection/{connection_id}/alter_table", json_data=args)


@register_tool("generate_table_by_description")
class GenerateTableByDescriptionTool(ToolDef):
    name = "generate_table_by_description"
    description = "通过自然语言描述让 AI 生成表结构（异步任务，返回 taskId）。需配合 get_ai_training_detail 轮询 taskId 获取生成结果"
    input_schema = {
        "type": "object",
        "properties": {
            "requirement": {"type": "string", "description": "业务需求描述"},
            "databaseId": {"type": "integer", "description": "关联的数据库 ID（可选）"},
        },
        "required": ["requirement"],
    }

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


@register_tool("create_database")
class CreateDatabaseTool(ToolDef):
    name = "create_database"
    description = "在内置数据源下创建一个数据库（建表前置步骤）"
    input_schema = {
        "type": "object",
        "properties": {
            "connectionId": {"type": "string", "description": "数据源连接 ID"},
            "databaseName": {"type": "string", "description": "数据库名（仅字母数字下划线）"},
        },
        "required": ["connectionId", "databaseName"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        connection_id = args.pop("connectionId")
        return await self.client.post(f"/datasource/connection/{connection_id}/create_database", json_data=args)


@register_tool("create_database_table")
class CreateDatabaseTableTool(ToolDef):
    name = "create_database_table"
    description = (
        "一次性创建数据库 + 表（合并接口，免去先建库再建表）。"
        "支持两种用法：①单表便捷参数 tableName/tableComment/columns；"
        "②批量传 tables 数组（一次建多张表）。二者任选其一"
    )
    # 单字段（columnName/columnType/...）的 schema，单表和批量两种用法共用
    _COLUMN_ITEMS = {
        "type": "object",
        "properties": {
            "columnName": {"type": "string", "description": "字段名"},
            "columnType": {"type": "string", "description": "字段类型（VARCHAR/INTEGER/SERIAL等）"},
            "columnLength": {"type": "integer", "description": "字段长度"},
            "isPrimaryKey": {"type": "boolean", "description": "是否主键"},
            "isNullable": {"type": "boolean", "description": "是否可空"},
            "isAutoIncrement": {"type": "boolean", "description": "是否自增"},
            "columnComment": {"type": "string", "description": "字段注释"},
            "defaultValue": {"type": "string", "description": "默认值"},
        },
        "required": ["columnName", "columnType"],
    }
    input_schema = {
        "type": "object",
        "properties": {
            "connectionId": {"type": "string", "description": "数据源连接 ID"},
            "databaseName": {"type": "string", "description": "数据库名（仅字母数字下划线）"},
            # —— 用法①：单表便捷参数 ——
            "tableName": {"type": "string", "description": "表名（用法①单表，小写字母+数字+下划线）"},
            "tableComment": {"type": "string", "description": "表注释（用法①单表）"},
            "columns": {
                "type": "array",
                "description": "字段定义数组（用法①单表，结构同 create_table）",
                "items": _COLUMN_ITEMS,
            },
            # —— 用法②：批量 tables 数组 ——
            "tables": {
                "type": "array",
                "description": "表定义数组（用法②批量建多表），每项含 tableName/tableComment/columns",
                "items": {
                    "type": "object",
                    "properties": {
                        "tableName": {"type": "string", "description": "表名"},
                        "tableComment": {"type": "string", "description": "表注释"},
                        "columns": {"type": "array", "description": "字段定义数组", "items": _COLUMN_ITEMS},
                    },
                    "required": ["tableName", "columns"],
                },
            },
        },
        "required": ["connectionId", "databaseName"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        connection_id = args.pop("connectionId")
        # 后端真实 body 结构：{databaseName, tables:[{tableName,tableComment,columns}]}（已真机探测确认）
        if not args.get("tables"):
            table = {"tableName": args.pop("tableName", None), "columns": args.pop("columns", [])}
            if args.get("tableComment") is not None:
                table["tableComment"] = args.pop("tableComment")
            args["tables"] = [table]
        else:
            # 批量用法下，清掉可能并存的单表字段，避免歧义
            args.pop("tableName", None)
            args.pop("tableComment", None)
            args.pop("columns", None)
        return await self.client.post(f"/datasource/connection/{connection_id}/create_database_table", json_data=args)


@register_tool("alter_database")
class AlterDatabaseTool(ToolDef):
    name = "alter_database"
    description = "修改数据库（如改名）"
    input_schema = {
        "type": "object",
        "properties": {
            "connectionId": {"type": "string", "description": "数据源连接 ID"},
            "databaseName": {"type": "string", "description": "当前数据库名"},
            "newName": {"type": "string", "description": "新数据库名"},
        },
        "required": ["connectionId", "databaseName", "newName"],
    }

    async def execute(self, args: dict) -> dict:
        args = dict(args)
        connection_id = args.pop("connectionId")
        # 后端改名字段名为 newName（已真机探测确认）；兼容历史传参 newDatabaseName
        if "newName" not in args and "newDatabaseName" in args:
            args["newName"] = args.pop("newDatabaseName")
        return await self.client.put(f"/datasource/connection/{connection_id}/alter_database", json_data=args)
