"""Schema 管理工具（DDL）"""

import json
from typing import Any

from mcp.types import Tool, TextContent

from trailbase_mcp.client.client import TrailBaseClient


def get_schema_tools() -> list[Tool]:
    """获取 Schema 相关工具"""
    return [
        Tool(
            name="schema.tables",
            description="列出所有表",
            inputSchema={
                "type": "object",
                "properties": {},
            },
        ),
        Tool(
            name="schema.create_table",
            description="创建表",
            inputSchema={
                "type": "object",
                "properties": {
                    "table": {"type": "string", "description": "表名"},
                    "columns": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string"},
                                "type": {"type": "string"},
                                "not_null": {"type": "boolean"},
                                "default": {"type": "string"},
                                "pk": {"type": "boolean"},
                                "unique": {"type": "boolean", "description": "列级唯一约束"},
                                "foreign_key": {
                                    "type": "object",
                                    "description": "外键约束",
                                    "properties": {
                                        "references_table": {"type": "string", "description": "引用的表名"},
                                        "references_column": {"type": "string", "description": "引用的列名"},
                                        "on_delete": {
                                            "type": "string",
                                            "description": "删除时的行为：CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                        "on_update": {
                                            "type": "string",
                                            "description": "更新时的行为：CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                    },
                                    "required": ["references_table", "references_column"],
                                },
                                "check": {"type": "string", "description": "CHECK 约束表达式，例如：age > 0"},
                            },
                            "required": ["name", "type"],
                        },
                        "description": "列定义",
                    },
                    "constraints": {
                        "type": "array",
                        "description": "表级约束",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "enum": ["UNIQUE", "CHECK", "FOREIGN_KEY"],
                                    "description": "约束类型",
                                },
                                "columns": {
                                    "type": "array",
                                    "items": {"type": "string"},
                                    "description": "约束涉及的列（用于 UNIQUE）",
                                },
                                "check_expr": {"type": "string", "description": "CHECK 约束表达式"},
                                "foreign_key": {
                                    "type": "object",
                                    "description": "外键约束（表级）",
                                    "properties": {
                                        "columns": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                            "description": "外键列",
                                        },
                                        "references_table": {"type": "string", "description": "引用的表名"},
                                        "references_columns": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                            "description": "引用的列名",
                                        },
                                        "on_delete": {
                                            "type": "string",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                        "on_update": {
                                            "type": "string",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                    },
                                    "required": ["columns", "references_table", "references_columns"],
                                },
                            },
                            "required": ["type"],
                        },
                    },
                    "if_not_exists": {"type": "boolean", "description": "如果不存在则创建"},
                },
                "required": ["table", "columns"],
            },
        ),
        Tool(
            name="schema.alter_table",
            description="修改表",
            inputSchema={
                "type": "object",
                "properties": {
                    "table": {"type": "string", "description": "表名"},
                    "add_columns": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string"},
                                "type": {"type": "string"},
                                "not_null": {"type": "boolean"},
                                "default": {"type": "string"},
                                "unique": {"type": "boolean", "description": "列级唯一约束"},
                                "foreign_key": {
                                    "type": "object",
                                    "description": "外键约束",
                                    "properties": {
                                        "references_table": {"type": "string", "description": "引用的表名"},
                                        "references_column": {"type": "string", "description": "引用的列名"},
                                        "on_delete": {
                                            "type": "string",
                                            "description": "删除时的行为：CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                        "on_update": {
                                            "type": "string",
                                            "description": "更新时的行为：CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                    },
                                    "required": ["references_table", "references_column"],
                                },
                                "check": {"type": "string", "description": "CHECK 约束表达式，例如：age > 0"},
                            },
                            "required": ["name", "type"],
                        },
                    },
                    "drop_columns": {
                        "type": "array",
                        "items": {"type": "string"},
                    },
                    "rename": {"type": "string", "description": "新表名"},
                    "add_constraints": {
                        "type": "array",
                        "description": "添加表级约束（注意：SQLite 不支持通过 ALTER TABLE 添加表级约束，此功能可能需要重建表）",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "enum": ["UNIQUE", "CHECK", "FOREIGN_KEY"],
                                    "description": "约束类型",
                                },
                                "columns": {
                                    "type": "array",
                                    "items": {"type": "string"},
                                    "description": "约束涉及的列（用于 UNIQUE）",
                                },
                                "check_expr": {"type": "string", "description": "CHECK 约束表达式"},
                                "foreign_key": {
                                    "type": "object",
                                    "description": "外键约束（表级）",
                                    "properties": {
                                        "columns": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                            "description": "外键列",
                                        },
                                        "references_table": {"type": "string", "description": "引用的表名"},
                                        "references_columns": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                            "description": "引用的列名",
                                        },
                                        "on_delete": {
                                            "type": "string",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                        "on_update": {
                                            "type": "string",
                                            "enum": ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"],
                                        },
                                    },
                                    "required": ["columns", "references_table", "references_columns"],
                                },
                            },
                            "required": ["type"],
                        },
                    },
                },
                "required": ["table"],
            },
        ),
        Tool(
            name="schema.drop_table",
            description="删除表",
            inputSchema={
                "type": "object",
                "properties": {
                    "table": {"type": "string", "description": "表名"},
                    "if_exists": {"type": "boolean", "description": "如果存在则删除"},
                },
                "required": ["table"],
            },
        ),
        Tool(
            name="schema.indexes",
            description="获取表的索引",
            inputSchema={
                "type": "object",
                "properties": {
                    "table": {"type": "string", "description": "表名"},
                },
                "required": ["table"],
            },
        ),
    ]


async def handle_schema_tables(
    client: TrailBaseClient,
) -> list[TextContent]:
    """处理 schema.tables 工具调用（复用 db.tables）"""
    try:
        sql = "SELECT name, type FROM sqlite_master WHERE type = 'table'"
        result = client.http.post("/api/_admin/query", json={"query": sql})
        # TrailBase API 返回格式: {"columns": [...], "rows": [[...], ...]}
        rows = result.get("rows", [])
        columns = result.get("columns", [])

        tables = []
        # rows 是二维数组，需要根据 columns 来映射
        for row in rows:
            # row 是值数组，需要根据 columns 来映射
            row_dict = {}
            if columns and len(row) == len(columns):
                for i, col in enumerate(columns):
                    # columns 可能是字典列表或字符串列表
                    if isinstance(col, dict):
                        col_name = col.get("name", f"col_{i}")
                    else:
                        col_name = str(col) if col else f"col_{i}"
                    row_dict[col_name] = row[i] if i < len(row) else None
            else:
                # 回退：假设 row 是字典
                row_dict = row if isinstance(row, dict) else {}
            
            table_name = row_dict.get("name")
            table_info: dict[str, Any] = {"name": table_name, "type": row_dict.get("type")}
            try:
                if table_name:
                    count_result = client.http.post(
                        "/api/_admin/query",
                        json={"query": f'SELECT COUNT(*) as count FROM "{table_name}"'},
                    )
                    count_rows = count_result.get("rows", [])
                    count_columns = count_result.get("columns", [])
                    if count_rows and len(count_rows) > 0:
                        # 获取第一行的第一个值
                        table_info["row_count"] = count_rows[0][0] if count_rows[0] else 0
            except Exception:
                pass
            tables.append(table_info)

        return [TextContent(type="text", text=json.dumps({"tables": tables}, ensure_ascii=False))]
    except Exception as e:
        return [TextContent(type="text", text=json.dumps({"error": str(e)}, ensure_ascii=False))]


async def handle_schema_create_table(
    client: TrailBaseClient,
    table: str,
    columns: list[dict[str, Any]],
    constraints: list[dict[str, Any]] | None = None,
    if_not_exists: bool | None = None,
) -> list[TextContent]:
    """处理 schema.create_table 工具调用"""
    try:
        parts = []
        
        # 处理列定义
        for col in columns:
            col_def = f'"{col["name"]}" {col["type"]}'
            if col.get("not_null"):
                col_def += " NOT NULL"
            if col.get("default") is not None:
                default_val = col["default"]
                # 如果已经是带引号的字符串（如 "'draft'"），直接使用
                if isinstance(default_val, str):
                    if default_val.startswith("'") and default_val.endswith("'"):
                        # 已经是带引号的字符串，直接使用
                        pass
                    elif not default_val.upper().startswith(("CURRENT_", "(")):
                        # 普通字符串值，需要加引号
                        default_val = f"'{default_val}'"
                col_def += f" DEFAULT {default_val}"
            if col.get("pk"):
                col_def += " PRIMARY KEY"
            if col.get("unique"):
                col_def += " UNIQUE"
            if col.get("check"):
                col_def += f" CHECK ({col['check']})"
            if col.get("foreign_key"):
                fk = col["foreign_key"]
                ref_table = fk["references_table"]
                ref_col = fk["references_column"]
                fk_def = f'REFERENCES "{ref_table}"("{ref_col}")'
                if fk.get("on_delete"):
                    fk_def += f" ON DELETE {fk['on_delete']}"
                if fk.get("on_update"):
                    fk_def += f" ON UPDATE {fk['on_update']}"
                col_def += f" {fk_def}"
            parts.append(col_def)

        # 处理表级约束
        if constraints:
            for constraint in constraints:
                constraint_type = constraint.get("type")
                if constraint_type == "UNIQUE":
                    cols = constraint.get("columns", [])
                    if cols:
                        cols_str = ", ".join(f'"{c}"' for c in cols)
                        parts.append(f"UNIQUE ({cols_str})")
                elif constraint_type == "CHECK":
                    check_expr = constraint.get("check_expr")
                    if check_expr:
                        parts.append(f"CHECK ({check_expr})")
                elif constraint_type == "FOREIGN_KEY":
                    fk = constraint.get("foreign_key", {})
                    fk_cols = fk.get("columns", [])
                    ref_table = fk.get("references_table")
                    ref_cols = fk.get("references_columns", [])
                    if fk_cols and ref_table and ref_cols:
                        fk_cols_str = ", ".join(f'"{c}"' for c in fk_cols)
                        ref_cols_str = ", ".join(f'"{c}"' for c in ref_cols)
                        fk_def = f'FOREIGN KEY ({fk_cols_str}) REFERENCES "{ref_table}"({ref_cols_str})'
                        if fk.get("on_delete"):
                            fk_def += f" ON DELETE {fk['on_delete']}"
                        if fk.get("on_update"):
                            fk_def += f" ON UPDATE {fk['on_update']}"
                        parts.append(fk_def)

        if_not_exists_clause = "IF NOT EXISTS " if if_not_exists else ""
        sql = f"CREATE TABLE {if_not_exists_clause}\"{table}\" ({', '.join(parts)})"

        result = client.http.post("/api/_admin/query", json={"query": sql})
        return [TextContent(type="text", text=json.dumps({"ok": True, "sql": sql}, ensure_ascii=False))]
    except Exception as e:
        return [TextContent(type="text", text=json.dumps({"error": str(e)}, ensure_ascii=False))]


async def handle_schema_alter_table(
    client: TrailBaseClient,
    table: str,
    add_columns: list[dict[str, Any]] | None = None,
    drop_columns: list[str] | None = None,
    rename: str | None = None,
    add_constraints: list[dict[str, Any]] | None = None,
) -> list[TextContent]:
    """处理 schema.alter_table 工具调用"""
    try:
        executed_sqls = []
        
        if rename:
            sql = f'ALTER TABLE "{table}" RENAME TO "{rename}"'
            client.http.post("/api/_admin/query", json={"query": sql})
            executed_sqls.append(sql)

        if add_columns:
            for col in add_columns:
                col_def = f'"{col["name"]}" {col["type"]}'
                if col.get("not_null"):
                    col_def += " NOT NULL"
                if col.get("default") is not None:
                    default_val = col["default"]
                    if isinstance(default_val, str):
                        if default_val.startswith("'") and default_val.endswith("'"):
                            pass
                        elif not default_val.upper().startswith(("CURRENT_", "(")):
                            default_val = f"'{default_val}'"
                    col_def += f" DEFAULT {default_val}"
                if col.get("unique"):
                    col_def += " UNIQUE"
                if col.get("check"):
                    col_def += f" CHECK ({col['check']})"
                if col.get("foreign_key"):
                    fk = col["foreign_key"]
                    ref_table = fk["references_table"]
                    ref_col = fk["references_column"]
                    fk_def = f'REFERENCES "{ref_table}"("{ref_col}")'
                    if fk.get("on_delete"):
                        fk_def += f" ON DELETE {fk['on_delete']}"
                    if fk.get("on_update"):
                        fk_def += f" ON UPDATE {fk['on_update']}"
                    col_def += f" {fk_def}"
                sql = f'ALTER TABLE "{table}" ADD COLUMN {col_def}'
                client.http.post("/api/_admin/query", json={"query": sql})
                executed_sqls.append(sql)

        if drop_columns:
            for col_name in drop_columns:
                sql = f'ALTER TABLE "{table}" DROP COLUMN "{col_name}"'
                client.http.post("/api/_admin/query", json={"query": sql})
                executed_sqls.append(sql)

        # 处理表级约束
        # 注意：SQLite 不支持通过 ALTER TABLE 直接添加表级约束
        # 需要重建表，这里返回提示信息
        if add_constraints:
            return [TextContent(
                type="text",
                text=json.dumps({
                    "error": "NotSupported",
                    "message": "SQLite 不支持通过 ALTER TABLE 添加表级约束（UNIQUE、CHECK、FOREIGN_KEY）",
                    "suggestion": "需要重建表来添加表级约束。可以使用以下步骤：\n1. 创建新表（包含约束）\n2. 复制数据\n3. 删除旧表\n4. 重命名新表",
                    "note": "列级约束（在 add_columns 中定义）已成功添加",
                    "executed_sqls": executed_sqls,
                }, ensure_ascii=False)
            )]

        return [TextContent(type="text", text=json.dumps({"ok": True, "executed_sqls": executed_sqls}, ensure_ascii=False))]
    except Exception as e:
        return [TextContent(type="text", text=json.dumps({"error": str(e)}, ensure_ascii=False))]


async def handle_schema_drop_table(
    client: TrailBaseClient,
    table: str,
    if_exists: bool | None = None,
) -> list[TextContent]:
    """处理 schema.drop_table 工具调用"""
    try:
        if_exists_clause = "IF EXISTS " if if_exists else ""
        sql = f'DROP TABLE {if_exists_clause}"{table}"'
        client.http.post("/api/_admin/query", json={"query": sql})
        return [TextContent(type="text", text=json.dumps({"ok": True}, ensure_ascii=False))]
    except Exception as e:
        return [TextContent(type="text", text=json.dumps({"error": str(e)}, ensure_ascii=False))]


async def handle_schema_indexes(
    client: TrailBaseClient,
    table: str,
) -> list[TextContent]:
    """处理 schema.indexes 工具调用"""
    try:
        indexes_sql = f'PRAGMA index_list("{table}")'
        indexes_result = client.http.post("/api/_admin/query", json={"query": indexes_sql})
        
        # 确保 indexes_result 是字典
        if not isinstance(indexes_result, dict):
            return [TextContent(type="text", text=f'{{"error": "Invalid response format: {type(indexes_result)}"}}')]
        
        indexes_rows = indexes_result.get("rows", [])
        if not isinstance(indexes_rows, list):
            return [TextContent(type="text", text=f'{{"error": "Invalid rows format: {type(indexes_rows)}"}}')]

        def extract_value(cell):
            """从单元格中提取值（处理 {'Text': 'value'} 或 {'Integer': 1} 格式）"""
            if isinstance(cell, dict):
                # 返回字典中的第一个值
                return next(iter(cell.values())) if cell else None
            return cell

        indexes = []
        for idx_row in indexes_rows:
            # PRAGMA index_list 返回格式: [seq, name, unique, origin, partial]
            # 直接使用固定顺序解析，不依赖 columns 信息
            idx_name = None
            idx_unique = False
            
            if isinstance(idx_row, list) and len(idx_row) >= 3:
                # 固定顺序: [seq, name, unique, origin, partial]
                idx_name = extract_value(idx_row[1]) if len(idx_row) > 1 else None
                idx_unique_val = extract_value(idx_row[2]) if len(idx_row) > 2 else None
                idx_unique = bool(idx_unique_val) if idx_unique_val is not None else False
            elif isinstance(idx_row, dict):
                idx_name = idx_row.get("name")
                idx_unique = bool(idx_row.get("unique", False))

            # 获取索引列信息
            idx_cols = []
            if idx_name:
                idx_info_sql = f'PRAGMA index_info("{idx_name}")'
                idx_info_result = client.http.post("/api/_admin/query", json={"query": idx_info_sql})
                idx_info_rows = idx_info_result.get("rows", [])
                idx_info_cols = idx_info_result.get("columns", [])

                for r in idx_info_rows:
                    # PRAGMA index_info 返回格式: [seqno, cid, name]
                    col_name = None
                    if isinstance(r, list) and len(r) >= 3:
                        col_name = extract_value(r[2])  # name 在第3个位置（索引2）
                    elif isinstance(r, dict):
                        col_name = r.get("name")
                    if col_name:
                        idx_cols.append(col_name)

            indexes.append(
                {
                    "name": idx_name,
                    "unique": idx_unique,
                    "columns": idx_cols,
                }
            )

        return [TextContent(type="text", text=json.dumps({"indexes": indexes}, ensure_ascii=False))]
    except Exception as e:
        return [TextContent(type="text", text=json.dumps({"error": str(e)}, ensure_ascii=False))]

