"""
IoT设备服务器主模块

该模块实现了一个简单的IoT设备控制服务器，使用FastMCP框架提供设备操作功能。
"""

import os
import json
from mcp.server.fastmcp import FastMCP
from .src.device_results_pretreatment import (
    format_devices_list,
)
from .src.device_operations import DeviceOperator
from .src.vector_service import VectorService
from .src.logger_config import get_logger
from .config import CONFIG
from .src.iot_device_dicts_prompt import (
    iot_get_devices_by_location_prompt,
    iot_get_all_spaces_and_devices_prompt,
    iot_device_precise_controller_prompt,
    smart_space_device_locator_matcher_prompt,
)
from .src.init_mcp import init_mcp_server

# 延迟初始化日志器，避免在导入时立即执行
logger = None

def _ensure_logger():
    """确保日志器已初始化"""
    global logger
    if logger is None:
        logger = get_logger(__name__)
    return logger

# 创建FastMCP实例
mcp = FastMCP("iot_device_server")
# 创建设备操作实例
device_op = DeviceOperator(api_base_url=CONFIG["device_api_base_url"])
# 创建向量服务实例
vector_service = VectorService(base_url=CONFIG["vector_api_base_url"])


@mcp.tool(description=iot_get_devices_by_location_prompt())
async def iot_get_devices_by_location(
    location: str,
) -> str:
    logger = _ensure_logger()
    try:
        # 输入参数验证
        if not location:
            error_msg = "location参数是必需的"
            logger.error(error_msg)
            return json.dumps(
                {"code": 400, "msg": error_msg, "data": None}, ensure_ascii=False
            )

        logger.info(
            f"开始处理IoT设备查询请求 - 位置: {location}"
        )

        # 从环境变量获取企业ID（已在启动时初始化）
        enterprise_id = os.environ.get("enterpriseId")
        if not enterprise_id:
            error_msg = f"企业ID未初始化，请检查员工ID配置"
            logger.error(error_msg)
            return json.dumps(
                {"code": 404, "msg": error_msg, "data": None}, ensure_ascii=False
            )

        logger.info(f"获取到企业ID: {enterprise_id}")

        # 查询设备列表
        query_result = vector_service.query_devices_by_location(
            keyId=enterprise_id,
            location=location
        )
        logger.info(f"查询设备列表结果: {query_result}")

        # 提取设备列表
        devices = query_result.get("devices", [])
        device_count = query_result.get("count", 0)
        
        if device_count == 0 or not devices:
            return json.dumps({
                "code": 404,
                "msg": f"在位置「{location}」未找到任何设备",
                "data": None
            }, ensure_ascii=False)
        
        # 使用格式化函数将设备列表转换为易读的文本
        formatted_text = format_devices_list(devices)
        logger.info(f"设备列表已格式化，设备数量: {device_count}")
        
        # 返回包含格式化文本和原始数据的结果
        result = {
            "code": 200,
            "msg": formatted_text,  # 直接将格式化文本放在msg字段
            "data": {
                "devices": devices,  # 原始设备数据，供后续操作使用
                "count": device_count,
                "location_filter": query_result.get("location_filter", location)
            }
        }
        
        return json.dumps(result, ensure_ascii=False)

    except Exception as e:
        error_msg = f"IoT设备查询过程中发生异常: {str(e)}"
        logger.error(error_msg, exc_info=True)
        return json.dumps(
            {"code": 500, "msg": error_msg, "data": None}, ensure_ascii=False
        )


@mcp.tool(description=iot_get_all_spaces_and_devices_prompt())
async def iot_get_all_spaces_and_devices() -> str:
    logger = _ensure_logger()
    try:
        logger.info("开始处理获取所有空间位置信息请求")

        # 从环境变量获取企业ID（已在启动时初始化）
        enterprise_id = os.environ.get("enterpriseId")
        if not enterprise_id:
            error_msg = f"企业ID未初始化，请检查员工ID配置"
            logger.error(error_msg)
            return json.dumps(
                {"code": 404, "msg": error_msg, "data": None}, ensure_ascii=False
            )

        logger.info(f"获取到企业ID: {enterprise_id}")

        # 查询所有设备（不指定位置，获取所有）
        query_result = vector_service.query_devices_by_location(
            keyId=enterprise_id,
            location=""  # 空字符串表示获取所有
        )
        logger.info(f"查询所有设备结果: {query_result}")

        # 提取设备列表
        devices = query_result.get("devices", [])
        device_count = query_result.get("count", 0)
        
        if device_count == 0 or not devices:
            return json.dumps({
                "code": 404,
                "msg": "系统中未找到任何设备和空间",
                "data": None
            }, ensure_ascii=False)
        
        # 提取所有唯一的空间名称
        spaces_set = set()
        for device in devices:
            # 提取空间信息
            location_desc = device.get("location_desc", "")
            if location_desc and location_desc != "未知空间":
                spaces_set.add(location_desc)
        
        # 转换为列表并排序
        spaces_list = sorted(list(spaces_set))
        
        if not spaces_list:
            return json.dumps({
                "code": 404,
                "msg": "系统中未找到任何有效空间",
                "data": None
            }, ensure_ascii=False)
        
        # 构建格式化文本
        formatted_lines = []
        formatted_lines.append("=" * 60)
        formatted_lines.append(f"所有空间位置信息")
        formatted_lines.append("=" * 60)
        formatted_lines.append(f"空间总数: {len(spaces_list)} 个")
        formatted_lines.append("")
        
        # 列出所有空间
        for space_idx, space_name in enumerate(spaces_list, 1):
            formatted_lines.append(f"{space_idx}. {space_name}")
        
        formatted_lines.append("")
        formatted_lines.append("=" * 60)
        formatted_text = "\n".join(formatted_lines)
        
        logger.info(f"已获取所有空间位置信息，空间数: {len(spaces_list)}")
        
        # 返回包含格式化文本和空间列表的结果
        result = {
            "code": 200,
            "msg": formatted_text,
            "data": {
                "spaces": spaces_list,  # 空间名称列表
                "space_count": len(spaces_list)
            }
        }
        
        return json.dumps(result, ensure_ascii=False)

    except Exception as e:
        error_msg = f"获取所有空间位置信息过程中发生异常: {str(e)}"
        logger.error(error_msg, exc_info=True)
        return json.dumps(
            {"code": 500, "msg": error_msg, "data": None}, ensure_ascii=False
        )


@mcp.tool(description=iot_device_precise_controller_prompt())
async def iot_device_precise_controller(
    entityId: str,
    command: str,
    params: dict = None,
    userId: str = None,
) -> str:
    logger = _ensure_logger()
    logger.info("=" * 60)
    logger.info("调用iot_device_precise_controller工具")
    logger.info(f"参数 - entityId: {entityId}, command: {command}, params: {params}, userId: {userId}")
    logger.info("=" * 60)
    
    try:
        # 输入参数验证
        logger.debug("开始参数验证...")
        if not all([entityId, command]):
            error_msg = "所有参数都是必需的: entityId,command"
            logger.error(f"参数验证失败: {error_msg}")
            return json.dumps(
                {"code": 400, "msg": error_msg, "data": None}, ensure_ascii=False
            )
        logger.debug("参数验证通过")

        # 从环境变量获取企业ID（已在启动时初始化）
        enterprise_id = os.environ.get("enterpriseId")
        if not enterprise_id:
            error_msg = f"企业ID未初始化，请检查员工ID配置"
            logger.error(error_msg)
            return json.dumps(
                {"code": 404, "msg": error_msg, "data": None}, ensure_ascii=False
            )

        logger.info(f"获取到企业ID: {enterprise_id}")

        map_result = {
            "enterpriseId": enterprise_id,
            "entityId": entityId,
            "command": command,
            "params": params if params is not None else {},
        }
        # 如果提供了userId，则添加到map_result中
        if userId:
            map_result["userId"] = userId
        # 操作设备
        result = device_op.operate_device(map_result)
        logger.info(f"设备操作结果: {result}")

        # 将结果字典转换为JSON字符串
        if isinstance(result, dict):
            result = json.dumps(result, ensure_ascii=False)

        logger.info("iot_device_precise_controller工具执行完成")
        logger.info("=" * 60)
        return result

    except Exception as e:
        error_msg = f"IoT设备操作过程中发生异常: {str(e)}"
        logger.error(error_msg, exc_info=True)
        logger.error("iot_device_precise_controller工具执行失败")
        logger.error("=" * 60)
        return json.dumps(
            {"code": 500, "msg": error_msg, "data": None}, ensure_ascii=False
        )

 

@mcp.tool(description=smart_space_device_locator_matcher_prompt())
async def smart_space_device_locator_matcher(
    userId: str,
) -> str:
    logger = _ensure_logger()
    try:
        if not userId:
            error_msg = "所有参数都是必需的: userId"
            logger.error(error_msg)
            return json.dumps(
                {"code": 400, "msg": error_msg, "data": None}, ensure_ascii=False
            )

        result = device_op.get_user_spaces_by_user_id(userId)
        if isinstance(result, dict):
            # 检查返回的data是否为None，如果是则提供友好的描述
            if result.get("data") is None:
                result["msg"] = "我目前还没发现您在哪里 请您告诉我你所属位置；"
            return json.dumps(result, ensure_ascii=False)
        return result
    except Exception as e:
        error_msg = f"定位空间过程中发生异常: {str(e)}"
        logger.error(error_msg, exc_info=True)
        return json.dumps(
            {"code": 500, "msg": error_msg, "data": None}, ensure_ascii=False
        )

def testFn() -> str:
    logger = _ensure_logger()
    try:
        # 读取test.json文件
        test_file_path = r"E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_iot\test.json"
        with open(test_file_path, "r", encoding="utf-8") as f:
            test_data = json.load(f)

        # 获取results数据
        results = test_data.get("results", [])
        logger.info(f"从test.json读取到的results数据: {results}")

        # 参数预处理
        map_result = device_op.preprocess_results(results)
        logger.info(f"参数预处理结果: {map_result}")

        # 保存map_result到本地JSON文件
        output_file_path = r"E:\yh-ai\project\lzwcai-szyg\lzwcai-mcp-server-package\lzwcai_mcp_iot\map_result.json"
        with open(output_file_path, "w", encoding="utf-8") as f:
            json.dump(map_result, f, ensure_ascii=False, indent=2)
        logger.info(f"map_result已保存到: {output_file_path}")

        return json.dumps(map_result, ensure_ascii=False)

    except FileNotFoundError:
        error_msg = "test.json文件未找到"
        logger.error(error_msg)
        return json.dumps(
            {"code": 404, "msg": error_msg, "data": None}, ensure_ascii=False
        )
    except json.JSONDecodeError as e:
        error_msg = f"test.json文件格式错误: {str(e)}"
        logger.error(error_msg)
        return json.dumps(
            {"code": 400, "msg": error_msg, "data": None}, ensure_ascii=False
        )
    except Exception as e:
        error_msg = f"测试过程中发生异常: {str(e)}"
        logger.error(error_msg, exc_info=True)
        return json.dumps(
            {"code": 500, "msg": error_msg, "data": None}, ensure_ascii=False
        )


def main():
    """主函数，启动MCP服务器"""
    logger = _ensure_logger()
    try:
        logger.info("=" * 80)
        logger.info("IoT设备MCP服务器启动流程开始")
        logger.info(f"配置信息: {CONFIG}")
        logger.info("=" * 80)

        # 初始化组件
        logger.info("正在初始化核心组件...")
        logger.info(f"设备操作器API地址: {CONFIG['device_api_base_url']}")
        logger.info(f"向量服务API地址: {CONFIG['vector_api_base_url']}")
        logger.info("核心组件初始化完成")

        # 获取企业ID并初始化MCP服务器
        enterprise_id = CONFIG.get("enterprise_id")
        if enterprise_id:
            logger.info(f"检测到企业ID配置: {enterprise_id}")
            logger.info("开始初始化MCP服务器...")
            
            init_result = init_mcp_server(device_op, vector_service, enterprise_id)
            logger.info(f"MCP服务器初始化结果: {init_result}")
            
            if init_result.get("code") != 200:
                logger.warning(f"MCP服务器初始化失败，但服务器仍将启动: {init_result}")
            else:
                logger.info("MCP服务器初始化成功")
                # 保存企业ID到环境变量
                returned_enterprise_id = init_result.get("data", {}).get("enterprise_id")
                if returned_enterprise_id:
                    device_op.set_enterprise_id_to_env(returned_enterprise_id)
                    logger.info(f"企业ID已保存到环境变量: {returned_enterprise_id}")
                else:
                    # 如果返回结果中没有enterprise_id，使用配置中的
                    device_op.set_enterprise_id_to_env(enterprise_id)
                    logger.info(f"企业ID已保存到环境变量: {enterprise_id}")
        else:
            logger.warning("未配置企业ID，跳过预初始化")
            logger.info("提示：您可以在配置文件或环境变量中设置ENTERPRISE_ID来启用自动初始化功能")

        # 注册的工具列表日志
        logger.info("已注册的MCP工具:")
        logger.info("1. iot_get_devices_by_location - 根据位置获取设备列表")
        logger.info("2. iot_get_all_spaces_and_devices - 获取所有空间位置信息")
        logger.info("3. iot_device_precise_controller - IoT设备精确控制")
        logger.info("4. smart_space_device_locator_matcher - 智能空间设备定位")

        logger.info("=" * 80)
        logger.info("MCP服务器即将启动，等待客户端连接...")
        logger.info("传输方式: stdio (标准输入输出)")
        logger.info("注意: 控制台日志已禁用，所有日志将写入文件")
        logger.info("=" * 80)

        # 使用标准输入输出作为传输方式运行服务器
        mcp.run(transport="stdio")
        
    except Exception as e:
        logger.error("=" * 80)
        logger.error(f"服务器启动失败: {str(e)}")
        logger.error("错误详情:", exc_info=True)
        logger.error("=" * 80)
        raise


if __name__ == "__main__":
    main()
