import asyncio
import json
import os

from dotenv import load_dotenv
from fastmcp import FastMCP, Client
from fastmcp.client.transports import StreamableHttpTransport

# Load environment variables from .env
load_dotenv()

# Zapier API config
server_url = "https://mcp.zapier.com/api/v1/connect"
api_key = os.getenv("ZAPIER_API_KEY")

# Create the MCP server
mcp = FastMCP("Zapier MCP")

# Global client reference
_client = None
_client_lock = asyncio.Lock()


async def get_client():
    """Get or create the Zapier client connection."""
    global _client
    async with _client_lock:
        if _client is None:
            transport = StreamableHttpTransport(
                server_url,
                headers={"Authorization": f"Bearer {api_key}"}
            )
            _client = Client(transport=transport)
            await _client.__aenter__()
        return _client


@mcp.tool()
async def list_zapier_tools() -> str:
    """List all available Zapier tools."""
    client = await get_client()
    tools = await client.list_tools()
    return json.dumps([{"name": t.name, "description": t.description} for t in tools], indent=2)


@mcp.tool()
async def gmail_send_email(instructions: str) -> str:
    """
    Create and send a new email message via Gmail.

    Args:
        instructions: Natural language instructions for the email (e.g., "Send an email to john@example.com with subject 'Hello' and body 'How are you?'") - WARNING - THIS IS THE ONLY PARAMETER. ALL PARAMETERS MUST BE WRITTEN IN PLAIN LANGUAGE.
    """
    client = await get_client()
    result = await client.call_tool("gmail_send_email", {"instructions": instructions})

    if result.content:
        content = result.content[0]
        if hasattr(content, 'text'):
            return content.text  # type: ignore
        return json.dumps({"status": "completed", "content_type": type(content).__name__})
    return json.dumps({"status": "completed"})


@mcp.tool()
async def call_zapier_tool(tool_name: str, parameters: str) -> str:
    """
    Call a Zapier tool with the given parameters.

    Args:
        tool_name: The name of the Zapier tool to call (e.g., "gmail_send_email")
        parameters: JSON string of parameters to pass to the tool
    """
    client = await get_client()
    params = json.loads(parameters) if parameters else {}
    result = await client.call_tool(tool_name, params)

    if result.content:
        content = result.content[0]
        if hasattr(content, 'text'):
            return content.text # type: ignore
        return json.dumps({"status": "completed", "content_type": type(content).__name__})
    return json.dumps({"status": "completed"})


if __name__ == "__main__":
    mcp.run()
