"""
Table management tools for PostgreSQL MCP Server
"""

import logging
from typing import Any, Dict, List, Callable, Coroutine
from mcp import Tool

from ..database import DatabaseManager, DatabaseError
from ..config import load_config

logger = logging.getLogger(__name__)


# Table management tools
create_table = Tool(
    name="create_table",
    description="Create a new table in PostgreSQL database",
    inputSchema={
        "type": "object",
        "properties": {
            "table_name": {
                "type": "string",
                "description": "Name of the table to create",
            },
            "columns": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string", "description": "Column name"},
                        "type": {
                            "type": "string",
                            "description": (
                                "Data type (e.g., VARCHAR(255), INTEGER, TEXT)"
                            ),
                        },
                        "nullable": {
                            "type": "boolean",
                            "default": True,
                            "description": "Whether column can be NULL",
                        },
                        "primary_key": {
                            "type": "boolean",
                            "default": False,
                            "description": "Whether column is primary key",
                        },
                        "unique": {
                            "type": "boolean",
                            "default": False,
                            "description": "Whether column has unique constraint",
                        },
                        "default": {
                            "type": "string",
                            "description": "Default value for the column",
                        },
                    },
                    "required": ["name", "type"],
                },
                "description": "Array of column definitions",
            },
            "if_not_exists": {
                "type": "boolean",
                "default": True,
                "description": "Create table only if it doesn't exist",
            },
        },
        "required": ["table_name", "columns"],
    },
)


alter_table = Tool(
    name="alter_table",
    description="Modify table structure in PostgreSQL database",
    inputSchema={
        "type": "object",
        "properties": {
            "table_name": {
                "type": "string",
                "description": "Name of the table to modify",
            },
            "operations": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "type": {
                            "type": "string",
                            "enum": [
                                "add_column",
                                "drop_column",
                                "alter_column",
                                "rename_column",
                            ],
                            "description": "Type of operation to perform",
                        },
                        "column_name": {
                            "type": "string",
                            "description": "Name of the column to operate on",
                        },
                        "new_column_name": {
                            "type": "string",
                            "description": (
                                "New name for the column (for rename operations)"
                            ),
                        },
                        "data_type": {
                            "type": "string",
                            "description": (
                                "Data type for the column (for add/alter operations)"
                            ),
                        },
                        "nullable": {
                            "type": "boolean",
                            "description": (
                                "Whether column can be NULL (for add/alter operations)"
                            ),
                        },
                        "default": {
                            "type": "string",
                            "description": (
                                "Default value for the column (for add/alter operations)"
                            ),
                        },
                    },
                    "required": ["type", "column_name"],
                },
                "description": "Array of operations to perform",
            },
        },
        "required": ["table_name", "operations"],
    },
)


drop_table = Tool(
    name="drop_table",
    description="Delete a table from PostgreSQL database",
    inputSchema={
        "type": "object",
        "properties": {
            "table_name": {
                "type": "string",
                "description": "Name of the table to delete",
            },
            "cascade": {
                "type": "boolean",
                "default": False,
                "description": "Also delete objects that depend on this table",
            },
            "if_exists": {
                "type": "boolean",
                "default": True,
                "description": "Don't throw error if table doesn't exist",
            },
        },
        "required": ["table_name"],
    },
)


# Table management tool handlers
async def handle_create_table(
    table_name: str, columns: List[Dict[str, Any]], if_not_exists: bool = True
) -> Dict[str, Any]:
    """Handle create table tool execution"""
    try:
        config = load_config()
        db_manager = DatabaseManager(config.postgres)

        # Connect to database
        db_manager.connection.connect()

        result = db_manager.create_table(table_name, columns, if_not_exists)

        # Disconnect from database
        db_manager.connection.disconnect()

        return result

    except DatabaseError as e:
        return {"success": False, "error": str(e)}
    except Exception as e:
        logger.error(f"Unexpected error in create_table: {e}")
        return {"success": False, "error": f"Internal server error: {str(e)}"}


async def handle_alter_table(
    table_name: str, operations: List[Dict[str, Any]]
) -> Dict[str, Any]:
    """Handle alter table tool execution"""
    try:
        config = load_config()
        db_manager = DatabaseManager(config.postgres)

        # Connect to database
        db_manager.connection.connect()

        result = db_manager.alter_table(table_name, operations)

        # Disconnect from database
        db_manager.connection.disconnect()

        return result

    except DatabaseError as e:
        return {"success": False, "error": str(e)}
    except Exception as e:
        logger.error(f"Unexpected error in alter_table: {e}")
        return {"success": False, "error": f"Internal server error: {str(e)}"}


async def handle_drop_table(
    table_name: str, cascade: bool = False, if_exists: bool = True
) -> Dict[str, Any]:
    """Handle drop table tool execution"""
    try:
        config = load_config()
        db_manager = DatabaseManager(config.postgres)

        # Connect to database
        db_manager.connection.connect()

        result = db_manager.drop_table(table_name, cascade, if_exists)

        # Disconnect from database
        db_manager.connection.disconnect()

        return result

    except DatabaseError as e:
        return {"success": False, "error": str(e)}
    except Exception as e:
        logger.error(f"Unexpected error in drop_table: {e}")
        return {"success": False, "error": f"Internal server error: {str(e)}"}


# Tool registry
def get_table_tools() -> List[Tool]:
    """Get all table management tools"""
    return [
        create_table,
        alter_table,
        drop_table,
    ]


def get_table_handlers() -> (
    Dict[str, Callable[..., Coroutine[Any, Any, Dict[str, Any]]]]
):
    """Get tool handlers for table management operations"""
    return {
        "create_table": handle_create_table,
        "alter_table": handle_alter_table,
        "drop_table": handle_drop_table,
    }
