#!/usr/bin/env python3
"""
API助手工具包

这个工具包集成了三个核心功能：
1. 获取接口参数信息
2. 调用指定接口API
3. 获取用户授权Token

使用lzwcai_mcp_dyntoolapi包中的方法，提供简洁易用的API操作接口。

作者: lzwcai
版本: 1.0.0
"""

import json
import asyncio
from typing import Dict, Any, Optional
import os
# 引入lzwcai_mcp_dyntoolapi包中的核心方法
from lzwcai_mcp_api_converter.src.business.get_business_api import get_business_api_details
from lzwcai_mcp_api_converter.src.core.api_base import ApiBase
from lzwcai_mcp_api_converter.src.core.core_server import call_api
from lzwcai_mcp_api_converter.src.core.get_auth import get_auth_data
from lzwcai_mcp_api_converter.src.core.api_auth_service import AuthService
from lzwcai_mcp_api_converter.src.util.logger_config import get_logger

# 配置日志
logger = get_logger(__name__)

# 全局AuthService实例（单例模式）
_auth_service_instance = None


def get_auth_service() -> AuthService:
    """
    获取全局共享的AuthService实例
    
    使用单例模式确保整个应用中只有一个AuthService实例，
    这样可以复用认证状态和连接，提高性能。
    
    Returns:
        AuthService: 全局共享的AuthService实例
        
    使用示例：
        >>> auth_service = get_auth_service()
        >>> token_result = await auth_service.authorize_request(user_id, business_system_id)
    """
    global _auth_service_instance
    if _auth_service_instance is None:
        logger.info("创建新的AuthService实例")
        _auth_service_instance = AuthService()
    return _auth_service_instance


# ==================== 功能1: 获取接口参数信息 ====================

def get_api_parameters_info(api_id: int, auth_token: str = None) -> Optional[Dict[str, Any]]:
    """
    获取指定接口ID的参数信息
    
    功能说明：
    - 根据接口ID获取接口的详细配置信息
    - 生成JSON Schema格式的参数定义
    - 返回包含参数列表、Schema、描述等完整信息的配置对象
    
    Args:
        api_id: 接口ID，例如 1957355058730684417
        auth_token: 认证token，如果不提供则使用默认token
        
    Returns:
        Dict[str, Any]: 处理后的接口配置对象，包含：
            - interfaceName: 拼音格式的接口名称
            - schema: JSON Schema格式的参数定义
            - schema_description: 完整的参数描述
            - 原始API配置的所有其他字段
            
    Raises:
        Exception: 当获取接口信息失败时抛出
        
    使用示例：
        >>> api_info = get_api_parameters_info(1957355058730684417)
        >>> print(api_info['interfaceName'])  # tool_AppZhangHaoMiMaDengLu
        >>> print(api_info['schema'])         # JSON Schema对象
    """
    try:
        logger.info(f"开始获取接口ID {api_id} 的参数信息...")
        
        # 步骤1: 调用业务接口获取API详情
        api_details = get_business_api_details([api_id], auth_token)
        
        if not api_details:
            logger.error(f"未找到接口ID {api_id} 的详情")
            return None
            
        # 获取第一个（也是唯一一个）API详情
        api_detail = api_details[0]
        
        # 步骤2: 使用ApiBase处理API配置，生成Schema
        api_base = ApiBase([api_detail])
        
        # 获取处理后的配置
        processed_configs = api_base.api_configs_map
        if not processed_configs:
            logger.error("API配置处理失败")
            return None
            
        processed_config = processed_configs[0]
        
        logger.info(f"成功获取接口 '{processed_config.get('interfaceName', 'N/A')}' 的参数信息")
        return processed_config
        
    except Exception as e:
        logger.error(f"获取接口参数信息失败: {str(e)}")
        raise


# ==================== 功能2: 调用指定接口API ====================

async def call_api_by_id(api_id: int, request_params: Dict[str, Any], auth_token: str = None) -> Optional[Dict[str, Any]]:
    """
    根据接口ID调用API
    
    功能说明：
    - 根据接口ID获取API配置
    - 智能处理认证（先尝试认证调用，失败后尝试无认证调用）
    - 发送HTTP请求并返回响应结果
    
    Args:
        api_id: 接口ID，例如 1957355058730684417
        request_params: 请求参数，格式如：
            {
                "body": {
                    "username": "test_user",
                    "password": "test_password"
                },
                "lzwcaiConfig": {
                    "userId": "test_user_id"
                }
            }
        auth_token: 认证token，如果不提供则使用默认token
        
    Returns:
        Dict[str, Any]: API调用结果
        
    Raises:
        Exception: 当API调用失败时抛出
        
    使用示例：
        >>> params = {
        ...     "body": {"username": "wangpeng1", "password": "Wp147258"},
        ...     "lzwcaiConfig": {"userId": "447"}
        ... }
        >>> result = await call_api_by_id(1957355058730684417, params)
        >>> print(result['code'])  # 200
    """
    try:
        logger.info(f"开始调用接口ID {api_id}...")
        
        # 步骤1: 获取API配置
        api_details = get_business_api_details([api_id], auth_token)
        
        if not api_details:
            logger.error(f"未找到接口ID {api_id} 的详情")
            return None
            
        # 获取第一个（也是唯一一个）API详情
        api_detail = api_details[0]
        
        # 步骤2: 使用ApiBase处理API配置
        api_base = ApiBase([api_detail])
        processed_configs = api_base.api_configs_map
        
        if not processed_configs:
            logger.error("API配置处理失败")
            return None
            
        processed_config = processed_configs[0]
        
        # 步骤3: 调用API
        logger.info(f"调用接口: {processed_config.get('interfaceName', 'N/A')}")
        logger.info(f"接口地址: {processed_config.get('apiUrl', 'N/A')}")
        logger.info(f"请求方法: {processed_config.get('method', 'N/A')}")
        
        # 判断是否需要认证
        need_auth = processed_config.get('authenticationRequired', 0) == 1
        logger.info(f"需要认证: {need_auth}")

        # 尝试调用API（智能认证处理）
        try:
            result = await call_api(processed_config, request_params, need_auth=need_auth)
        except Exception as api_error:
            # 如果认证失败，尝试不需要认证的方式调用
            if "认证失败" in str(api_error) or "鉴权令牌失败" in str(api_error):
                logger.warning(f"认证调用失败，尝试无认证调用: {str(api_error)}")
                try:
                    result = await call_api(processed_config, request_params, need_auth=False)
                    logger.info("无认证调用成功")
                except Exception as no_auth_error:
                    logger.error(f"无认证调用也失败: {str(no_auth_error)}")
                    # 返回模拟的错误响应，展示调用过程
                    result = {
                        "error": "API调用失败",
                        "auth_error": str(api_error),
                        "no_auth_error": str(no_auth_error),
                        "note": "这是一个模拟的错误响应，展示了API调用的完整过程"
                    }
            else:
                raise api_error
        
        logger.info("API调用成功")
        return result
        
    except Exception as e:
        logger.error(f"调用API失败: {str(e)}")
        raise


# ==================== 功能3: 获取用户授权Token ====================

def get_auth_info(user_id: str, business_system_id: str) -> Optional[Dict[str, Any]]:
    """
    获取用户认证信息
    
    功能说明：
    - 获取用户在指定业务系统中的认证配置
    - 包含认证类型、API密钥、登录接口等信息
    
    Args:
        user_id: 用户ID，例如 "447"
        business_system_id: 业务系统ID，例如 "1957354824118095874"
        
    Returns:
        Dict[str, Any]: 认证信息，包括：
            - authType: 认证类型
            - name: 业务系统名称
            - apiKey: API密钥
            - apiVO: API配置信息
            
    Raises:
        Exception: 当获取认证信息失败时抛出
        
    使用示例：
        >>> auth_info = get_auth_info("447", "1957354824118095874")
        >>> print(auth_info['data']['authType'])  # 1
    """
    try:
        logger.info(f"开始获取用户 {user_id} 在业务系统 {business_system_id} 的认证信息...")

        # 调用get_auth_data获取认证数据
        auth_data = get_auth_data(user_id, business_system_id)

        if not auth_data:
            logger.error("未能获取到认证数据")
            return None

        logger.info("成功获取认证信息")
        return auth_data

    except Exception as e:
        logger.error(f"获取认证信息失败: {str(e)}")
        raise


async def get_business_token(user_id: str, business_system_id: str,persist_token: bool = False) -> Optional[Dict[str, Any]]:
    """
    获取用户在指定业务系统的Token
    
    功能说明：
    - 使用全局共享的AuthService实例获取Token
    - 复用认证状态，提高性能
    
    Args:
        user_id: 用户ID
        business_system_id: 业务系统ID
        
    Returns:
        Dict[str, Any]: Token获取结果
        
    Raises:
        Exception: 当获取Token失败时抛出
        
    使用示例：
        >>> token_result = await get_business_token("447", "1957354824118095874")
        >>> print(token_result.get('success'))  # True
    """
    try:
        logger.info(f"开始获取用户 {user_id} 在业务系统 {business_system_id} 的Token...")

        # 使用全局共享的AuthService实例获取Token
        auth_service = get_auth_service()
        token_result = await auth_service.authorize_request(user_id, business_system_id,persist_token=persist_token)

        logger.info("Token获取完成")
        return token_result

    except Exception as e:
        logger.error(f"获取业务Token失败: {str(e)}")
        raise


# ==================== 便捷工具函数 ====================

def save_result_to_file(data: Dict[str, Any], filename: str) -> None:
    """
    保存结果到JSON文件
    
    Args:
        data: 要保存的数据
        filename: 文件名
    """
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        logger.info(f"💾 数据已保存到: {filename}")
    except Exception as e:
        logger.error(f"保存文件失败: {str(e)}")


def print_api_info(api_info: Dict[str, Any]) -> None:
    """
    格式化打印API信息
    
    Args:
        api_info: API信息字典
    """
    logger.info("\n" + "="*60)
    logger.info("📋 接口信息:")
    logger.info(f"接口名称: {api_info.get('interfaceName', 'N/A')}")
    logger.info(f"业务描述: {api_info.get('businessPrompts', 'N/A')}")
    logger.info(f"接口地址: {api_info.get('apiUrl', 'N/A')}")
    logger.info(f"请求方法: {api_info.get('method', 'N/A')}")
    logger.info(f"需要认证: {'是' if api_info.get('authenticationRequired', 0) == 1 else '否'}")
    logger.info("="*60)


def print_api_result(result: Dict[str, Any]) -> None:
    """
    格式化打印API调用结果
    
    Args:
        result: API调用结果
    """
    logger.info("\n" + "="*60)
    logger.info("📥 API调用结果:")
    if result.get('success') is not None:
        status = "✅ 成功" if result.get('success') else "❌ 失败"
        logger.info(f"状态: {status}")
    if result.get('code') is not None:
        logger.info(f"状态码: {result.get('code')}")
    if result.get('msg'):
        logger.info(f"消息: {result.get('msg')}")
    logger.info("="*60)


# ==================== 便捷使用示例 ====================

async def demo_usage():
    """
    使用示例演示
    
    展示如何使用工具包的三个核心功能
    """
    logger.info("🚀 API助手工具包使用示例")
    
    # 测试数据
    # api_id = 1957355058730684417
    user_id = "2"
    business_system_id = "1922839602141347842"
    # os.environ["lzwcai_mcp_dyntoolapi_auth_url"] = (
    # "http://lzwcai-demp-corp-manager:8086/system/mcpServer/bizSys/api/getByIds"
    # )
    try:
        # get_auth_info_data=await get_business_token(user_id, business_system_id)
        # print(f"获取接口参数信息: {get_auth_info_data}")
        # # 功能1: 获取接口参数信息
        # print(f"\n📋 功能1: 获取接口ID {api_id} 的参数信息")
        # api_info = get_api_parameters_info(api_id)
        # if api_info:
        #     print(f"✅ 接口名称: {api_info.get('interfaceName', 'N/A')}")
        #     print(f"✅ 业务描述: {api_info.get('businessPrompts', 'N/A')}")
        
        # # 功能2: 调用API
        # print(f"\n🔧 功能2: 调用接口ID {api_id}")
        # request_params = {
        #     "body": {
        #         "username": "wangpeng1",
        #         "password": "Wp147258"
        #     },
        #     "lzwcaiConfig": {
        #         "userId": user_id
        #     }
        # }
        # api_result = await call_api_by_id(api_id, request_params)
        # if api_result:
        #     print(f"✅ API调用成功: {api_result.get('msg', 'N/A')}")
        
        #         # 功能3: 获取Token
        # logger.info(f"\n🔑 功能3: 获取用户 {user_id} 的Token")
        token_result = await get_business_token(user_id, business_system_id)
        if token_result and token_result.get('success'):
            logger.info(f"✅ Token获取成功: {token_result.get('msg', 'N/A')}")
        
        logger.info(f"\n🎉 所有功能演示完成！")
        
    except Exception as e:
        logger.error(f"❌ 演示过程中发生错误: {str(e)}")


if __name__ == "__main__":
    # 运行使用示例
    asyncio.run(demo_usage())
