from pathlib import Path
from typing import Any
import asyncio
import logging

# 支持直接运行和模块导入两种方式
try:
    from .utils import load_json, generate_tool_name, generate_input_schema
    from .utils import get_skill_by_id, DataSourceAPIClient, process_skill_response, test_sql_with_schema
    from .utils import get_database_id, get_datasource_id, get_skill_id, get_env_config
    from .utils.logger_config import logger_config
except ImportError:
    from utils import load_json, generate_tool_name, generate_input_schema
    from utils import get_skill_by_id, DataSourceAPIClient, process_skill_response, test_sql_with_schema
    from utils import get_database_id, get_datasource_id, get_skill_id, get_env_config
    from utils.logger_config import logger_config

from mcp.server.models import InitializationOptions
from mcp.server import NotificationOptions, Server
import mcp.types as types

# 初始化 MCP 专用日志器
mcp_logger = logger_config.setup_mcp_logging()

# ========== 数据源配置 ==========
# 数据源类型常量
DATA_SOURCE_API = "api"      # 仅使用API数据
DATA_SOURCE_LOCAL = "local"  # 仅使用本地JSON数据
DATA_SOURCE_BOTH = "both"    # 合并本地和API数据

# 默认数据源（可修改）
DEFAULT_DATA_SOURCE = DATA_SOURCE_LOCAL
# ================================


def get_queries():
    """
    获取业务查询配置
    
    Returns:
        list: 包含所有业务查询配置的列表
    """
    try:
        # 获取当前文件所在目录
        current_dir = Path(__file__).parent
        
        # 构建 businessQueries.json 的路径
        json_path = current_dir / "businessQueries.json"
        
        mcp_logger.debug(f"正在读取业务查询配置文件: {json_path}")
        
        # 使用 load_json 方法读取 JSON 文件
        queries = load_json(json_path)
        
        mcp_logger.info(f"成功加载 {len(queries)} 个业务查询配置")
        
        return queries
    except Exception as e:
        mcp_logger.error(f"加载业务查询配置失败: {e}", exc_info=True)
        raise


def generate_tool_schema_from_query(query: dict) -> types.Tool:
    """
    根据查询配置生成 MCP 工具模式
    
    Args:
        query: 单个查询配置字典
        
    Returns:
        types.Tool: MCP 工具对象
    """
    try:
        # 获取参数定义并生成 inputSchema
        parameters = query.get('parameters', {})
        input_schema = generate_input_schema(parameters)
        
        # 生成工具名称（格式: tool_拼音_id）
        # tool_name = generate_tool_name(query['businessName'], query['id'])
        tool_name = query['businessName']
        # 构建工具描述，包含业务名称和业务描述
        description = f"{query['businessName']}: {query['businessDescription']}"
        
        mcp_logger.debug(f"生成工具模式: {tool_name} - {query['businessName']}")
        
        return types.Tool(
            name=tool_name,
            description=description,
            inputSchema=input_schema
        )
    except Exception as e:
        mcp_logger.error(f"生成工具模式失败: {query.get('id', 'unknown')}, 错误: {e}", exc_info=True)
        raise


# 创建 MCP 服务器实例
server = Server("lzwcai-mcpskills-mfg-data-agentv2")

# 缓存查询配置，避免重复加载
_queries_cache = None


async def get_queries_cache(source: str = None):
    """
    获取或初始化查询配置缓存
    
    Args:
        source: 数据源类型（默认使用 DEFAULT_DATA_SOURCE）
            - "api": 仅使用API数据
            - "local": 仅使用本地JSON数据
            - "both": 合并本地和API数据
    
    Returns:
        查询配置列表
    """
    global _queries_cache
    if _queries_cache is None:
        source = source or DEFAULT_DATA_SOURCE
        mcp_logger.info(f"初始化查询配置（数据源: {source}）...")
        
        if source == DATA_SOURCE_LOCAL:
            _queries_cache = get_queries()
            mcp_logger.info(f"本地配置: {len(_queries_cache)} 条")
            
        elif source == DATA_SOURCE_API:
            try:
                _queries_cache = await call_third_party_api()
                mcp_logger.info(f"API配置: {len(_queries_cache)} 条")
                mcp_logger.info(f"API配置数组: {_queries_cache}")
            except Exception as e:
                mcp_logger.warning(f"API获取失败，降级使用本地配置: {e}")
                _queries_cache = get_queries()
                
        else:  # DATA_SOURCE_BOTH
            local = get_queries()
            try:
                api = await call_third_party_api()
            except Exception as e:
                mcp_logger.warning(f"API获取失败: {e}")
                api = []
            _queries_cache = local + api
            mcp_logger.info(f"配置总数: {len(_queries_cache)} 条（本地{len(local)}+API{len(api)}）")
        
    return _queries_cache


@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
    """
    列出所有动态生成的 MCP 工具
    
    Returns:
        list[types.Tool]: 所有可用的工具列表
    """
    try:
        mcp_logger.info("收到列出工具请求")
        
        queries = await get_queries_cache()
        tools = []
        
        for query in queries:
            tool = generate_tool_schema_from_query(query)
            tools.append(tool)
        
        mcp_logger.info(f"成功生成 {len(tools)} 个 MCP 工具")
        mcp_logger.debug(f"工具列表: {[tool.name for tool in tools]}")
        
        return tools
    except Exception as e:
        mcp_logger.error(f"列出工具失败: {e}", exc_info=True)
        raise


@server.call_tool()
async def handle_call_tool(
    name: str, 
    arguments: dict[str, Any] | None
) -> list[types.TextContent]:
    """
    处理工具调用请求
    
    Args:
        name: 工具名称
        arguments: 工具参数
        
    Returns:
        list[types.TextContent]: 工具执行结果（返回参数和对应的接口配置）
    """
    try:
        mcp_logger.info(f"收到工具调用请求: {name}")
        mcp_logger.debug(f"工具参数: {arguments}")
        
        # 获取查询配置缓存
        queries = await get_queries_cache()
        
        # 根据工具名称查找对应的 item（接口配置）
        tool_item = None
        for query in queries:
            # tool_name = generate_tool_name(query['businessName'], query['id'])
            tool_name = query['businessName']
            if tool_name == name:
                tool_item = query
                break
        
        # 构建返回结果
        import json
        
        if tool_item:
            request_data = {
                "datasourceId": get_datasource_id(),
                "businessName": tool_item.get("businessName"),
                "businessDescription": tool_item.get("businessDescription"),
                "sqlTemplate": tool_item.get("sqlTemplate"),
                "parameters": tool_item.get("parameters"),
                "testParams": arguments or {}
            }
            
            # 如果 arguments 中有 targetDatabaseName 且有值，添加到 request_data
            if arguments and arguments.get("targetDatabaseName"):
                request_data["targetDatabaseName"] = arguments["targetDatabaseName"]
                mcp_logger.debug(f"添加目标数据库名称: {arguments['targetDatabaseName']}")
            
            # 调用测试SQL API
            try:
                mcp_logger.info("正在调用测试SQL API...")
                api_response = test_sql_with_schema(request_data)
                mcp_logger.info("测试SQL API调用成功")
                
                # 返回包含 data 字段的结果
                result = {
                    "success": True,
                    "data": api_response
                }
                result_text = json.dumps(result, ensure_ascii=False, indent=2)
                
            except Exception as e:
                error_msg = f"调用测试SQL API失败: {str(e)}"
                mcp_logger.error(error_msg, exc_info=True)
                result = {
                    "success": False,
                    "error": error_msg,
                    "data": None
                }
                result_text = json.dumps(result, ensure_ascii=False, indent=2)
        else:
            error_msg = f"未找到工具 {name} 对应的配置"
            result = {
                "success": False,
                "error": error_msg,
                "data": None
            }
            result_text = json.dumps(result, ensure_ascii=False, indent=2)
        
        mcp_logger.debug(f"工具调用结果: {result_text}")
        
        return [
            types.TextContent(
                type="text",
                text=result_text
            )
        ]
    except Exception as e:
        error_msg = f"工具调用失败: {name}, 错误: {e}"
        mcp_logger.error(error_msg, exc_info=True)
        return [
            types.TextContent(
                type="text",
                text=f"错误: {error_msg}"
            )
        ]


async def call_third_party_api(skill_id: str = None) -> list:
    """
    调用第三方API获取技能信息并返回处理后的数据
    
    Args:
        skill_id: 技能ID（默认从环境变量 SKILL_ID 读取，如果未设置则使用 1981000305474482178）
        
    Returns:
        处理后的查询配置列表（businessQueries格式）
        
    Example:
        queries = await call_third_party_api()
        # 返回: [{"id": "...", "businessName": "...", ...}, ...]
    """
    try:
        # 如果没有传入 skill_id，则从环境变量读取
        if skill_id is None:
            skill_id = get_skill_id()
        
        mcp_logger.info(f"调用第三方API，skill_id: {skill_id}")
        
        # 获取原始数据
        raw_result = get_skill_by_id(skill_id)

        mcp_logger.info(f"成功{raw_result}")
        
        # 处理并返回
        processed_queries = process_skill_response(raw_result)
        
        mcp_logger.info(f"成功获取并处理 {len(processed_queries)} 条数据")
        return processed_queries
        
    except Exception as e:
        mcp_logger.error(f"API调用失败: {e}", exc_info=True)
        raise


async def async_main():
    """MCP 服务器异步主函数"""
    try:
        mcp_logger.info("=" * 60)
        mcp_logger.info("正在启动 MCP 服务器: lzwcai-mcpskills-analyzeOrder")
        mcp_logger.info("版本: 0.1.0")
        mcp_logger.info("=" * 60)
        
        # 输出环境配置信息
        env_config = get_env_config()
        mcp_logger.info(f"环境配置 - Database ID: {env_config['database_id']}")
        mcp_logger.info(f"环境配置 - Datasource ID: {env_config['datasource_id']}")
        mcp_logger.info(f"环境配置 - Skill ID: {env_config['skill_id']}")
        mcp_logger.info(f"环境配置 - Backend Base URL: {env_config['backend_base_url']}")
        mcp_logger.info("=" * 60)
        
        from mcp.server.stdio import stdio_server
        
        async with stdio_server() as (read_stream, write_stream):
            mcp_logger.info("MCP 服务器已启动，等待客户端连接...")
            
            await server.run(
                read_stream,
                write_stream,
                InitializationOptions(
                    server_name="lzwcai-mcpskills-analyzeOrder",
                    server_version="0.1.0",
                    capabilities=server.get_capabilities(
                        notification_options=NotificationOptions(),
                        experimental_capabilities={},
                    ),
                ),
            )
            
        mcp_logger.info("MCP 服务器已关闭")
        
    except Exception as e:
        mcp_logger.error(f"MCP 服务器运行失败: {e}", exc_info=True)
        raise


def main():
    """入口点函数（用于 console_scripts）"""
    try:
        # 初始化系统日志
        # MCP协议使用stdio通信，必须禁用控制台输出以避免干扰JSON-RPC通信
        logger_config.setup_logging(
            app_name="lzwcai_mcp_sqlexecutor",
            log_level=logging.INFO,
            console_output=False  # 禁用控制台输出
        )
        
        mcp_logger.info("开始运行 MCP SQL Executor 服务器")
        asyncio.run(async_main())
        
    except KeyboardInterrupt:
        mcp_logger.info("收到中断信号，正在关闭服务器...")
    except Exception as e:
        mcp_logger.error(f"程序运行失败: {e}", exc_info=True)
        raise


if __name__ == "__main__":
    main()
