"""
G-Prophet MCP Server
Exposes G-Prophet External API as MCP tools for AI agents.

Usage as CLI (after pip install gprophet[mcp]):
    export GPROPHET_API_KEY=gp_sk_...
    gprophet-mcp

Or add to mcp.json:
    {
        "mcpServers": {
            "gprophet": {
                "command": "gprophet-mcp",
                "env": { "GPROPHET_API_KEY": "gp_sk_..." }
            }
        }
    }
"""

import os
import sys
import json
import logging
import asyncio

import httpx

logger = logging.getLogger(__name__)

API_KEY = ""
BASE_URL = ""


def _api_request(method: str, path: str, params: dict = None, json_body: dict = None) -> dict:
    """Make an API request to G-Prophet."""
    with httpx.Client(
        base_url=BASE_URL,
        headers={"X-API-Key": API_KEY},
        timeout=120,
    ) as client:
        resp = client.request(method, path, params=params, json=json_body)
        return resp.json()


def _format_result(data: dict) -> str:
    """Format API response for MCP output."""
    return json.dumps(data, indent=2, ensure_ascii=False)


def _build_tools():
    """Build tool definitions. Import mcp here to keep it lazy."""
    from mcp.types import Tool

    return [
        Tool(
            name="gprophet_predict",
            description="Predict stock/crypto price using AI. Markets: US, CN, HK, CRYPTO. Algorithms: auto, gprophet2026v1, lstm, transformer, random_forest, ensemble.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string", "description": "Stock/crypto symbol (e.g., AAPL, 600519, BTCUSDT)"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                    "days": {"type": "integer", "minimum": 1, "maximum": 30, "default": 7},
                    "algorithm": {"type": "string", "default": "auto"},
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_quote",
            description="Get real-time stock/crypto quote.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string", "description": "Stock/crypto symbol"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_batch_quote",
            description="Get quotes for multiple symbols at once (max 20).",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbols": {"type": "array", "items": {"type": "string"}, "description": "List of symbols"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                },
                "required": ["symbols"],
            },
        ),
        Tool(
            name="gprophet_history",
            description="Get historical OHLCV price data.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                    "period": {"type": "string", "enum": ["1w", "1m", "3m", "6m", "1y", "2y"], "default": "3m"},
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_search",
            description="Search for stocks/crypto by keyword.",
            inputSchema={
                "type": "object",
                "properties": {
                    "keyword": {"type": "string"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 50, "default": 10},
                },
                "required": ["keyword"],
            },
        ),
        Tool(
            name="gprophet_technical",
            description="Calculate technical indicators (RSI, MACD, Bollinger, KDJ, SMA, EMA) and generate trading signals.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                    "indicators": {
                        "type": "array",
                        "items": {"type": "string", "enum": ["rsi", "macd", "bollinger", "kdj", "sma", "ema"]},
                        "default": ["rsi", "macd", "bollinger", "kdj"],
                    },
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_fear_greed",
            description="Get crypto market Fear & Greed Index.",
            inputSchema={
                "type": "object",
                "properties": {
                    "days": {"type": "integer", "minimum": 1, "maximum": 365, "default": 1},
                },
            },
        ),
        Tool(
            name="gprophet_market_overview",
            description="Get market overview: breadth, hot concepts, major indices.",
            inputSchema={
                "type": "object",
                "properties": {
                    "market": {"type": "string", "enum": ["CN", "US"], "default": "CN"},
                },
            },
        ),
        Tool(
            name="gprophet_analyze_stock",
            description="Run AI stock analysis report (58 points). Returns task_id for async polling.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string"},
                    "market": {"type": "string", "enum": ["US", "CN", "CRYPTO"], "default": "US"},
                    "locale": {"type": "string", "enum": ["zh-CN", "en-US"], "default": "en-US"},
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_analyze_comprehensive",
            description="Run multi-agent comprehensive analysis (150 points). Returns task_id for async polling.",
            inputSchema={
                "type": "object",
                "properties": {
                    "symbol": {"type": "string"},
                    "market": {"type": "string", "enum": ["US", "CN", "HK", "CRYPTO"], "default": "US"},
                    "locale": {"type": "string", "enum": ["zh-CN", "en-US"], "default": "en-US"},
                },
                "required": ["symbol"],
            },
        ),
        Tool(
            name="gprophet_task_status",
            description="Check the status of an async analysis task.",
            inputSchema={
                "type": "object",
                "properties": {
                    "task_id": {"type": "string", "description": "Task ID returned by analysis endpoints"},
                },
                "required": ["task_id"],
            },
        ),
        Tool(
            name="gprophet_balance",
            description="Check current points balance and API quota.",
            inputSchema={"type": "object", "properties": {}},
        ),
        Tool(
            name="gprophet_info",
            description="Get API metadata: supported markets, algorithms, pricing.",
            inputSchema={"type": "object", "properties": {}},
        ),
    ]


def _dispatch(name: str, args: dict) -> dict:
    """Route tool calls to API endpoints."""

    if name == "gprophet_predict":
        return _api_request("POST", "/predictions/predict", json_body={
            "symbol": args["symbol"],
            "market": args.get("market", "US"),
            "days": args.get("days", 7),
            "algorithm": args.get("algorithm", "auto"),
        })

    if name == "gprophet_quote":
        return _api_request("GET", "/market-data/quote", params={
            "symbol": args["symbol"], "market": args.get("market", "US")
        })

    if name == "gprophet_batch_quote":
        return _api_request("POST", "/market-data/batch-quote", json_body={
            "symbols": args["symbols"], "market": args.get("market", "US")
        })

    if name == "gprophet_history":
        return _api_request("GET", "/market-data/history", params={
            "symbol": args["symbol"], "market": args.get("market", "US"),
            "period": args.get("period", "3m")
        })

    if name == "gprophet_search":
        return _api_request("GET", "/market-data/search", params={
            "keyword": args["keyword"], "market": args.get("market", "US"),
            "limit": args.get("limit", 10)
        })

    if name == "gprophet_technical":
        return _api_request("POST", "/technical/analyze", json_body={
            "symbol": args["symbol"], "market": args.get("market", "US"),
            "indicators": args.get("indicators", ["rsi", "macd", "bollinger", "kdj"])
        })

    if name == "gprophet_fear_greed":
        return _api_request("GET", "/sentiment/fear-greed", params={
            "days": args.get("days", 1)
        })

    if name == "gprophet_market_overview":
        return _api_request("GET", "/sentiment/market-overview", params={
            "market": args.get("market", "CN")
        })

    if name == "gprophet_analyze_stock":
        return _api_request("POST", "/analysis/stock", json_body={
            "symbol": args["symbol"], "market": args.get("market", "US"),
            "locale": args.get("locale", "en-US")
        })

    if name == "gprophet_analyze_comprehensive":
        return _api_request("POST", "/analysis/comprehensive", json_body={
            "symbol": args["symbol"], "market": args.get("market", "US"),
            "locale": args.get("locale", "en-US")
        })

    if name == "gprophet_task_status":
        return _api_request("GET", f"/analysis/task/{args['task_id']}")

    if name == "gprophet_balance":
        return _api_request("GET", "/account/balance")

    if name == "gprophet_info":
        return _api_request("GET", "/info")

    return {"error": f"Unknown tool: {name}"}


def main():
    """Entry point for the gprophet-mcp CLI command."""
    try:
        from mcp.server import Server
        from mcp.server.stdio import stdio_server
        from mcp.types import TextContent
    except ImportError:
        print(
            "Error: MCP dependencies not installed.\n"
            "Install with: pip install gprophet[mcp]",
            file=sys.stderr,
        )
        sys.exit(1)

    global API_KEY, BASE_URL
    API_KEY = os.environ.get("GPROPHET_API_KEY", "")
    BASE_URL = os.environ.get("GPROPHET_BASE_URL", "https://gprophet.com/api/external/v1")

    if not API_KEY:
        print("Error: GPROPHET_API_KEY environment variable is required", file=sys.stderr)
        sys.exit(1)

    server = Server("gprophet")
    tools = _build_tools()

    @server.list_tools()
    async def list_tools():
        return tools

    @server.call_tool()
    async def call_tool(name: str, arguments: dict):
        try:
            result = _dispatch(name, arguments)
            return [TextContent(type="text", text=_format_result(result))]
        except Exception as e:
            return [TextContent(type="text", text=f"Error: {e}")]

    async def _run():
        async with stdio_server() as (read_stream, write_stream):
            await server.run(read_stream, write_stream, server.create_initialization_options())

    asyncio.run(_run())


if __name__ == "__main__":
    main()
