"""Test module for demonstrating MCPClient functionality."""

# pylint: disable=too-many-return-statements,too-many-statements

import asyncio
import json

from reme.core.utils import MCPClient


async def main():
    """Execute demonstration of the MCPClient."""
    test_mcp = "test_mcp"
    config_data = {
        "mcpServers": {
            test_mcp: {
                "url": "http://127.0.0.1:8010/sse",
            },
        },
    }

    client = MCPClient(config_data)

    try:
        # List all available tools
        print("=" * 50)
        print("Listing available tools:")
        print("=" * 50)
        t_list = await client.list_tool_calls(test_mcp)
        for t in t_list:
            print(json.dumps(t, ensure_ascii=False, indent=2))

        # Helper function to build default values
        def build_default_value(param_info: dict) -> any:
            """Build a default value for a parameter based on its schema."""
            param_type = param_info.get("type", "string")

            # Handle enum types - use the first enum value
            if "enum" in param_info and param_info["enum"]:
                return param_info["enum"][0]

            # Handle different types
            if param_type == "string":
                return "example_string"
            elif param_type == "number":
                return 0.0
            elif param_type == "integer":
                return 0
            elif param_type == "boolean":
                return False
            elif param_type == "array":
                return []
            elif param_type == "object":
                # Recursively build nested objects
                obj = {}
                nested_properties = param_info.get("properties", {})
                nested_required = param_info.get("required", [])

                for nested_param_name in nested_required:
                    if nested_param_name in nested_properties:
                        nested_param_info = nested_properties[nested_param_name]
                        obj[nested_param_name] = build_default_value(nested_param_info)

                return obj
            else:
                return None

        # Call tools if available
        if t_list:
            # Execute the first two tools (or fewer if not enough tools available)
            tools_to_execute = min(2, len(t_list))

            for idx in range(tools_to_execute):
                print("\n" + "=" * 50)
                print(f"Calling tool #{idx + 1}:")
                print("=" * 50)

                # Get the tool's information
                current_tool = t_list[idx]
                tool_type = current_tool.get("type", "function")
                tool_body = current_tool.get(tool_type, {})

                tool_name = tool_body.get("name")
                tool_description = tool_body.get("description", "")

                # Prepare arguments based on the tool's input schema
                tool_arguments = {}
                parameters = tool_body.get("parameters", {})
                properties = parameters.get("properties", {})
                required = parameters.get("required", [])

                # Build minimal arguments for required parameters
                for param_name in required:
                    if param_name in properties:
                        param_info = properties[param_name]
                        tool_arguments[param_name] = build_default_value(param_info)

                # Validate tool name exists
                if not tool_name:
                    print("Error: Tool name not found in the tool definition")
                    print(f"Tool structure: {json.dumps(current_tool, ensure_ascii=False, indent=2)}")
                else:
                    print(f"Tool name: {tool_name}")
                    print(f"Tool description: {tool_description}")
                    print(f"Arguments: {json.dumps(tool_arguments, ensure_ascii=False, indent=2)}")

                    # Call the tool
                    result = await client.call_tool(test_mcp, tool_name, tool_arguments, parse_text_result=True)

                    print("\n" + "-" * 50)
                    print("Tool call result:")
                    print("-" * 50)
                    print(f"Content: {result}")
                    if hasattr(result, "isError"):
                        print(f"Is Error: {result.isError}")
        else:
            print("\nNo tools available to call.")

    except Exception as e:
        print(f"Error occurred: {e}")
        import traceback

        traceback.print_exc()


if __name__ == "__main__":
    asyncio.run(main())
