"""
Schema 转换器
将 sqlParams 数组格式转换为 MCP 工具需要的 JSON Schema 格式

支持的类型:
- string: 文本输入
- paragraph: 段落/多行文本
- select: 下拉选项
- number: 数字输入
"""
import json
from typing import Any


def convert_param_to_schema_property(param: dict) -> tuple[str, dict, bool]:
    """
    将单个参数转换为 JSON Schema property
    
    Args:
        param: 参数配置，格式如:
            {
                "type": "string",
                "name": "param_name",
                "displayName": "参数显示名",
                "maxLength": 200,
                "defaultValue": "",
                "required": true,
                "options": ["选项1", "选项2"]  # 仅 select 类型
            }
    
    Returns:
        tuple: (property_name, property_schema, is_required)
    """
    param_type = param.get("type", "string")
    param_name = param.get("name", "")
    display_name = param.get("displayName", param_name)
    default_value = param.get("defaultValue", "")
    max_length = param.get("maxLength")
    is_required = param.get("required", False)
    options = param.get("options", [])
    
    property_schema = {
        "description": display_name
    }
    
    if param_type == "string":
        property_schema["type"] = "string"
        if max_length:
            property_schema["maxLength"] = max_length
            
    elif param_type == "paragraph":
        property_schema["type"] = "string"
        property_schema["format"] = "paragraph"
        if max_length:
            property_schema["maxLength"] = max_length
            
    elif param_type == "select":
        property_schema["type"] = "string"
        if options:
            property_schema["enum"] = options
            
    elif param_type == "number":
        property_schema["type"] = "number"

    elif param_type == "boolean":
        property_schema["type"] = "boolean"
        # Boolean default handling
        if default_value is not None and str(default_value).lower() in ("true", "false", "1", "0"):
             property_schema["default"] = str(default_value).lower() in ("true", "1")

    elif param_type == "array":
        property_schema["type"] = "array"
        # Simple array of strings by default if no item type specified
        # For more complex arrays, we might need extended config in sqlParams
        property_schema["items"] = {"type": "string"}
    
    elif param_type == "object":
        property_schema["type"] = "object"
        # Allow any object structure by default
        property_schema["additionalProperties"] = True
        
    else:
        # 默认当作 string 处理
        property_schema["type"] = "string"
    
    # 添加默认值
    if default_value not in (None, ""):
        if param_type == "number":
            try:
                property_schema["default"] = int(default_value) if str(default_value).isdigit() else float(default_value)
            except (ValueError, TypeError):
                property_schema["default"] = default_value
        else:
            property_schema["default"] = default_value
    
    return param_name, property_schema, is_required


def convert_sql_params_to_input_schema(sql_params: str | list) -> dict:
    """
    将 sqlParams 转换为 MCP 工具的 inputSchema
    
    Args:
        sql_params: sqlParams 字段值，可以是 JSON 字符串或已解析的列表
            格式: [{"type": "string", "name": "xxx", ...}, ...]
    
    Returns:
        dict: MCP 工具的 inputSchema，格式如:
            {
                "type": "object",
                "properties": {...},
                "required": [...]
            }
    """
    # 解析 JSON 字符串
    if isinstance(sql_params, str):
        try:
            params_list = json.loads(sql_params)
        except json.JSONDecodeError:
            return {"type": "object", "properties": {}, "required": []}
    else:
        params_list = sql_params
    
    if not isinstance(params_list, list):
        return {"type": "object", "properties": {}, "required": []}
    
    input_schema = {
        "type": "object",
        "properties": {},
        "required": []
    }
    
    for param in params_list:
        if not isinstance(param, dict):
            continue
            
        name, schema, is_required = convert_param_to_schema_property(param)
        
        if name:
            input_schema["properties"][name] = schema
            if is_required:
                input_schema["required"].append(name)
    
    return input_schema


def convert_tool_config_to_mcp_tool(config: dict) -> dict:
    """
    将单个工具配置转换为 MCP Tool 配置
    
    Args:
        config: 工具配置对象
    
    Returns:
        dict: MCP Tool 配置
    """
    name = config.get("name", "")
    description = config.get("description") or config.get("toolPrompt", "")
    sql_params = config.get("sqlParams", "[]")
    
    input_schema = convert_sql_params_to_input_schema(sql_params)
    
    return {
        "name": name,
        "description": description,
        "inputSchema": input_schema,
        "_raw": config  # 保留原始数据
    }


# 测试用
if __name__ == "__main__":
    # 测试单个参数转换
    test_param = {
        "type": "select",
        "name": "operation",
        "displayName": "运算符",
        "required": True,
        "options": ["+", "-", "*", "/"]
    }
    
    name, schema, required = convert_param_to_schema_property(test_param)
    print(f"参数名: {name}")
    print(f"Schema: {json.dumps(schema, ensure_ascii=False, indent=2)}")
    print(f"必填: {required}")
