"""
AkShare MCP Server
提供 AkShare 金融数据接口的 MCP 服务

重构版本：只保留两个核心工具
1. search_functions - 智能搜索函数（支持多关键词、可选详情）
2. execute_function - 执行函数获取数据
"""

from __future__ import annotations

import json
from typing import Any, Dict, Optional
from fastmcp import FastMCP
from pydantic import BaseModel, Field

# 导入查询和执行器
try:
    from .query import search_functions as search_functions_impl
    from .executor import AkShareExecutor
except ImportError:
    from query import search_functions as search_functions_impl
    from executor import AkShareExecutor


# 创建 FastMCP 实例
mcp = FastMCP("AkShare MCP Server")


class SearchFunctionsRequest(BaseModel):
    """函数搜索请求"""
    keyword: Optional[str] = Field(
        default=None, 
        description="搜索关键词，支持空格分隔多个关键词进行组合搜索。例如：'stock zh hist' 可以搜索A股历史数据相关函数"
    )
    limit: int = Field(
        default=10, 
        description="返回数量限制，默认10"
    )
    include_detail: bool = Field(
        default=False,
        description="是否返回函数的详细信息（包含完整参数列表、类型、默认值等）。False=简略信息，True=完整详情"
    )


class ExecuteFunctionRequest(BaseModel):
    """执行函数请求"""
    function_name: str = Field(..., description="函数名，可通过 search_functions 工具查找")
    params: Dict[str, Any] = Field(default_factory=dict, description="函数参数字典")


# 初始化执行器
executor = AkShareExecutor()


@mcp.tool()
def search_functions(request: SearchFunctionsRequest) -> str:
    """
    搜索 AkShare 函数
    
    智能搜索功能，支持多关键词组合搜索，可选返回详细信息。
    
    【使用场景】
    1. 快速浏览：keyword="stock", include_detail=False
       - 快速查看有哪些股票相关函数
    
    2. 精确搜索：keyword="stock zh hist", include_detail=True
       - 搜索A股历史数据函数，并获取完整参数信息
       - 多个关键词用空格分隔，会匹配同时包含所有关键词的函数
    
    3. 分类查询：
       - "stock zh spot" - A股实时行情
       - "fund etf" - ETF基金
       - "futures main" - 期货主力合约
       - "macro china gdp" - 中国GDP数据
    
    【搜索技巧】
    - 函数名中的下划线会被当作空格处理，所以 "stock hist" 可以匹配 "stock_zh_a_hist"
    - 支持中英文混合搜索
    - 关键词越多，结果越精确
    
    【返回格式】
    - include_detail=False: 返回函数名、简短描述、参数名列表
    - include_detail=True: 返回完整信息，包括参数类型、默认值、参数说明等
    
    Args:
        request: 搜索请求
        
    Returns:
        JSON格式的搜索结果
    """
    try:
        result = search_functions_impl(
            keyword=request.keyword,
            limit=request.limit,
            include_detail=request.include_detail
        )
        return json.dumps(result, ensure_ascii=False, indent=2)
        
    except Exception as e:
        error_response = {
            "success": False,
            "error": str(e),
            "data": None
        }
        return json.dumps(error_response, ensure_ascii=False, indent=2)


@mcp.tool()
def execute_function(request: ExecuteFunctionRequest) -> str:
    """
    执行 AkShare 函数获取数据
    
    调用指定的 AkShare 函数并返回数据结果。
    
    【使用流程】
    1. 使用 search_functions 搜索需要的函数
       例如：search_functions(keyword="stock zh hist", include_detail=True)
    
    2. 查看返回的函数信息，了解参数要求
    
    3. 使用 execute_function 执行函数
       例如：execute_function(function_name="stock_zh_a_hist", params={"symbol": "000001"})
    
    【常用示例】
    
    1. 获取A股实时行情（无参数）：
       function_name="stock_zh_a_spot_em"
       params={}
    
    2. 获取股票历史数据：
       function_name="stock_zh_a_hist"
       params={
           "symbol": "000001",
           "period": "daily",
           "start_date": "20240101",
           "end_date": "20241231"
       }
    
    3. 获取中国GDP数据（无参数）：
       function_name="macro_china_gdp"
       params={}
    
    4. 获取期货主力合约：
       function_name="futures_main_sina"
       params={
           "symbol": "CU0",
           "start_date": "20240101",
           "end_date": "20241231"
       }
    
    【注意事项】
    - 参数名和值必须与函数要求完全匹配
    - 日期格式通常为 "YYYYMMDD"
    - 股票代码不需要加市场前缀（如 "000001" 而不是 "sz000001"）
    - 某些函数可能需要较长时间执行，请耐心等待
    
    Args:
        request: 包含函数名和参数的请求
        
    Returns:
        JSON格式的执行结果，包含数据和元信息
    """
    try:
        result = executor.execute_function(
            function_name=request.function_name,
            params=request.params
        )
        
        response = {
            "success": True,
            "data": result,
            "count": len(result) if isinstance(result, list) else 1,
            "function": request.function_name,
            "params": request.params
        }
        return json.dumps(response, ensure_ascii=False, indent=2)
        
    except Exception as e:
        error_response = {
            "success": False,
            "error": str(e),
            "data": None,
            "function": request.function_name,
            "params": request.params
        }
        return json.dumps(error_response, ensure_ascii=False, indent=2)


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


def main():
    """命令行入口点函数"""
    mcp.run()
