"""Horizon SDK MCP Server.

Exposes the Horizon trading engine as MCP tools for Claude Code,
Cursor, Claude Desktop, and other MCP-compatible clients.

Run: python -m horizon.mcp
"""

from __future__ import annotations

from mcp.server.fastmcp import FastMCP

from horizon import tools

mcp = FastMCP(
    "horizon-sdk",
    instructions=(
        "Horizon SDK — prediction market trading engine. "
        "Use these tools to check positions, submit orders, manage risk, "
        "discover markets, and compute Kelly-optimal sizing on Polymarket and Kalshi."
    ),
)


# ---------------------------------------------------------------------------
# Tools
# ---------------------------------------------------------------------------

@mcp.tool()
def engine_status() -> dict:
    """Get trading engine status: PnL, open orders, positions, kill switch state, uptime."""
    return tools.engine_status()


@mcp.tool()
def list_positions() -> list[dict]:
    """List all open positions with size, entry price, PnL, and exchange."""
    return tools.list_positions()


@mcp.tool()
def list_open_orders(market_id: str | None = None) -> list[dict]:
    """List open orders. Optionally filter by market_id."""
    return tools.list_open_orders(market_id)


@mcp.tool()
def list_recent_fills(limit: int = 20) -> list[dict]:
    """List recent trade fills. Default last 20."""
    return tools.list_recent_fills(limit)


@mcp.tool()
def submit_order(market_id: str, side: str, price: float, size: float) -> dict:
    """Submit a limit order. side: 'buy' or 'sell'. price: 0-1 (probability). Returns order ID."""
    return tools.submit_order(market_id, side, price, size)


@mcp.tool()
def cancel_order(order_id: str) -> dict:
    """Cancel a single order by its ID."""
    return tools.cancel_order(order_id)


@mcp.tool()
def cancel_all_orders() -> dict:
    """Cancel ALL open orders across all exchanges. Use with caution."""
    return tools.cancel_all_orders()


@mcp.tool()
def cancel_market_orders(market_id: str) -> dict:
    """Cancel all orders for a specific market."""
    return tools.cancel_market_orders(market_id)


@mcp.tool()
def activate_kill_switch(reason: str) -> dict:
    """EMERGENCY STOP. Activates the kill switch and cancels all orders. Use only in emergencies."""
    return tools.activate_kill_switch(reason)


@mcp.tool()
def deactivate_kill_switch() -> dict:
    """Deactivate the kill switch to resume normal trading."""
    return tools.deactivate_kill_switch()


@mcp.tool()
def get_feed_snapshot(name: str) -> dict:
    """Get the latest price/bid/ask snapshot for a named feed."""
    return tools.get_feed_snapshot(name)


@mcp.tool()
def list_all_feeds() -> list[dict]:
    """List all active feed snapshots with current prices."""
    return tools.list_all_feeds()


@mcp.tool()
def discover_markets(exchange: str = "polymarket", query: str = "", limit: int = 10) -> list[dict]:
    """Search for prediction markets on Polymarket or Kalshi. Returns market name, ID, and metadata."""
    return tools.discover(exchange, query, limit)


@mcp.tool()
def kelly_sizing(
    prob: float,
    price: float,
    bankroll: float = 1000.0,
    fraction: float = 0.25,
    max_size: float = 100.0,
) -> dict:
    """Compute Kelly-optimal position size. prob: estimated probability (0-1). price: market price (0-1)."""
    return tools.kelly_sizing(prob, price, bankroll, fraction, max_size)


@mcp.tool()
def check_parity(market_id: str) -> dict:
    """Check YES/NO price parity for a market. Detects if prices deviate from summing to 1.0."""
    return tools.check_parity(market_id)


@mcp.tool()
def add_stop_loss(
    market_id: str, side: str, order_side: str, size: float, trigger: float
) -> dict:
    """Add a stop-loss order. side: 'yes'/'no'. order_side: 'buy'/'sell'. Triggers at price."""
    return tools.add_stop_loss(market_id, side, order_side, size, trigger)


@mcp.tool()
def add_take_profit(
    market_id: str, side: str, order_side: str, size: float, trigger: float
) -> dict:
    """Add a take-profit order. side: 'yes'/'no'. order_side: 'buy'/'sell'. Triggers at price."""
    return tools.add_take_profit(market_id, side, order_side, size, trigger)


@mcp.tool()
def list_contingent_orders() -> list[dict]:
    """List all pending stop-loss and take-profit orders."""
    return tools.list_contingent_orders()


# ---------------------------------------------------------------------------
# Resources
# ---------------------------------------------------------------------------

@mcp.resource("horizon://status")
def resource_status() -> str:
    """Current engine status as JSON context."""
    import json
    return json.dumps(tools.engine_status(), indent=2)


@mcp.resource("horizon://positions")
def resource_positions() -> str:
    """Current positions as JSON context."""
    import json
    return json.dumps(tools.list_positions(), indent=2)


# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------

def main() -> None:
    """Run the MCP server on stdio transport."""
    mcp.run(transport="stdio")
