"""
向量服务模块

该模块提供了向量数据的增删改查操作接口。
"""

import requests
import json
from typing import Dict, Any, Optional, List
from ..config import CONFIG
from .logger_config import get_logger

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

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


class VectorService:
    """向量服务类，提供向量数据的增删改查功能"""

    def __init__(self, base_url: str = None):
        """
        初始化向量服务

        参数:
            base_url: API服务的基础URL
        """
        logger = _ensure_logger()
        self.base_url = base_url or CONFIG["vector_api_base_url"]
        self.session = requests.Session()
        # 设置默认超时
        self.session.timeout = CONFIG["request_timeout"]
        logger.info(f"VectorService初始化完成，API基础URL: {self.base_url}")

    def init_vector_store(
        self,
        keyId: str,
    ) -> Dict[str, Any]:
        """
        调用初始化向量存储API接口

        参数:
            keyId: 企业或项目的唯一标识符

        返回:
            Dict[str, Any]: API返回的响应数据
        """
        if not keyId or not isinstance(keyId, str):
            error_msg = "keyId参数是必需的且必须是字符串"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

        endpoint = f"{self.base_url}/iot/companies/recreate"

        # 构建请求数据
        payload = {
            "company_id": keyId,
            "company_name": "公司名称",
            "enterprise_id": keyId,
            "description": "公司描述",
        }

        # 设置请求头
        headers = {"Content-Type": "application/json"}

        try:
            logger.info(f"初始化向量库，keyId: {keyId}")
            # 发送POST请求
            response = self.session.post(
                endpoint,
                headers=headers,
                data=json.dumps(payload),
                timeout=CONFIG["request_timeout"],
            )
            # 检查响应状态
            response.raise_for_status()
            # 返回JSON响应
            result = response.json()
            logger.info(f"向量库初始化成功: {result}")
            return result

        except requests.exceptions.Timeout:
            error_msg = f"向量库初始化请求超时，keyId: {keyId}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except requests.RequestException as e:
            error_msg = f"向量库初始化API请求失败: {str(e)}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except Exception as e:
            error_msg = f"向量库初始化发生未知异常: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

    def delete_vector(self, keyId: str) -> Dict[str, Any]:
        """
        删除向量数据（模拟实现）

        参数:
            keyId: 要删除的向量唯一标识

        返回:
            Dict[str, Any]: 包含删除结果的字典
        """
        if not keyId or not isinstance(keyId, str):
            error_msg = "keyId参数是必需的且必须是字符串"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

        logger.info(f"删除向量数据，keyId: {keyId}")
        # 模拟删除向量的结果
        return {
            "status": "success",
            "message": "向量删除成功",
            "data": {"keyId": keyId, "deleted_at": "2023-07-15T11:45:00Z"},
        }

    def update_vector(
        self,
        keyId: str,
    ) -> Dict[str, Any]:
        """
        更新向量数据

        参数:
            keyId: 要更新的向量唯一标识

        返回:
            Dict[str, Any]: 包含更新结果的字典
        """
        if not keyId or not isinstance(keyId, str):
            error_msg = "keyId参数是必需的且必须是字符串"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

        endpoint = f"{self.base_url}/iot/vector-store/update"

        # 构建请求数据
        payload = {"keyId": keyId}

        # 设置请求头
        headers = {"Content-Type": "application/json"}

        try:
            logger.info(f"更新向量数据，keyId: {keyId}")
            # 发送POST请求
            response = self.session.post(
                endpoint,
                headers=headers,
                data=json.dumps(payload),
                timeout=CONFIG["request_timeout"],
            )
            # 检查响应状态
            response.raise_for_status()
            # 返回JSON响应
            result = response.json()
            logger.info(f"向量数据更新成功: {result}")
            return result

        except requests.exceptions.Timeout:
            error_msg = f"向量数据更新请求超时，keyId: {keyId}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except requests.RequestException as e:
            error_msg = f"更新向量数据失败: {str(e)}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except Exception as e:
            error_msg = f"更新向量数据发生未知异常: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

    def query_vector(
        self,
        keyId: str,
        device: Optional[str] = None,
        location: Optional[str] = None,
        operation: Optional[str] = None,
        operation_param: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        查询向量数据

        参数:
            keyId: 企业或项目的唯一标识符
            device: 设备名称（可选）
            location: 设备位置（可选）
            operation: 操作类型（可选）
            operation_param: 操作参数（可选）

        返回:
            Dict[str, Any]: 包含查询结果的字典
        """
        if not keyId or not isinstance(keyId, str):
            error_msg = "keyId参数是必需的且必须是字符串"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

        # 验证至少有一个查询参数
        if not any([device, location, operation]):
            error_msg = "至少需要提供device、location或operation中的一个参数"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

        endpoint = f"{self.base_url}/iot/companies/{keyId}/search"

        # 构建请求数据
        payload = {}

        # 添加可选参数
        if device:
            payload["device"] = device
        if location:
            payload["location"] = location
        if operation:
            payload["operation"] = operation
        if operation_param:
            payload["operation_param"] = operation_param

        # 设置请求头
        headers = {
            "Content-Type": "application/json",
        }

        try:
            logger.info(
                f"查询向量数据，keyId: {keyId}, device: {device}, location: {location}, operation: {operation}, operation_param: {operation_param}"
            )
            # 发送POST请求
            response = self.session.post(
                endpoint,
                headers=headers,
                data=json.dumps(payload),
                timeout=CONFIG["request_timeout"],
            )
            # 检查响应状态
            response.raise_for_status()
            # 返回JSON响应
            result = response.json()
            logger.info(
                f"向量查询成功，返回结果数量: {result.get('data', {}).get('total_results', 0)}"
            )
            return result

        except requests.exceptions.Timeout:
            error_msg = f"向量查询请求超时，keyId: {keyId}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except requests.RequestException as e:
            error_msg = f"查询向量数据失败: {str(e)}"
            logger.error(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }
        except Exception as e:
            error_msg = f"查询向量数据发生未知异常: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {
                "status": "error",
                "message": error_msg,
                "data": None,
            }

    def analyze_search_results(self, search_results: List[List[Any]]) -> Dict[str, Any]:
        """
        调用搜索结果分析接口
        
        参数:
            search_results: 搜索结果数据，格式为包含设备信息、评分和详细评分的嵌套数组
                           [[device_info, score, score_details], ...]
        
        返回:
            Dict[str, Any]: 分析结果，包含处理后的数据和响应信息
        """
        logger.info("开始分析搜索结果...")
        logger.debug(f"输入搜索结果数量: {len(search_results) if search_results else 0}")
        
        if not search_results or not isinstance(search_results, list):
            error_msg = "无效的搜索结果数据：search_results必须是一个非空数组"
            logger.error(error_msg)
            return {"code": 400, "msg": error_msg, "data": None}

        # API配置
        url = f"{self.base_url}/iot/analyze/search-results"
        headers = {"Content-Type": "application/json"}

        # 构建请求数据
        request_data = {
            "search_results": search_results
        }

        try:
            logger.info(f"正在调用搜索结果分析接口: {url}")
            logger.debug(f"请求数据大小: {len(search_results)} 条搜索结果")

            # 发送POST请求
            response = self.session.post(
                url=url,
                headers=headers,
                data=json.dumps(request_data),
                timeout=CONFIG["request_timeout"],
            )

            # 处理响应
            if response.status_code == 200:
                try:
                    result = response.json()
                    logger.info(f"搜索结果分析成功，返回数据类型: {type(result)}")
                    
                    # 处理标准格式的响应 {code, msg, data}
                    if isinstance(result, dict) and "code" in result:
                        # 检查接口返回的业务状态码
                        if result.get("code") == 200:
                            data = result.get("data", {})
                            filtered_results = data.get("filtered_results", [])
                            logger.info(f"搜索结果分析成功，返回过滤结果数量: {len(filtered_results) if filtered_results else 0}")
                            # 返回包含filtered_results的标准格式
                            return filtered_results
                        else:
                            # 接口返回了错误状态码，直接返回原始响应
                            logger.warning(f"接口返回业务错误: code={result.get('code')}, msg={result.get('msg')}")
                            return result
                    
                    # 如果接口直接返回数据而不是标准格式，包装成标准格式
                    if isinstance(result, dict) and "code" not in result:
                        logger.info("接口返回非标准格式，进行包装处理")
                        return {"code": 200, "msg": "分析成功", "data": result}
                    
                    logger.debug(f"返回原始分析结果: {type(result)}")
                    return result
                except ValueError as e:
                    error_msg = f"响应JSON解析失败: {str(e)}"
                    logger.error(error_msg)
                    return {"code": 500, "msg": error_msg, "data": None}
            else:
                error_msg = f"API请求失败，状态码: {response.status_code}, 响应: {response.text}"
                logger.error(error_msg)
                return {
                    "code": response.status_code,
                    "msg": error_msg,
                    "data": None,
                }

        except requests.exceptions.Timeout:
            error_msg = "搜索结果分析接口请求超时"
            logger.error(error_msg)
            return {"code": 408, "msg": error_msg, "data": None}
        except requests.exceptions.RequestException as e:
            error_msg = f"搜索结果分析接口网络请求异常: {str(e)}"
            logger.error(error_msg)
            return {"code": 500, "msg": error_msg, "data": None}
        except Exception as e:
            error_msg = f"搜索结果分析接口调用异常: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {"code": 500, "msg": error_msg, "data": None}

    def check_vector_store_status(self, keyId: str) -> bool:
        """
        检查向量库状态

        参数:
            keyId: 企业或项目的唯一标识符

        返回:
            bool: 向量库是否存在
        """
        if not keyId or not isinstance(keyId, str):
            logger.error(f"无效的keyId参数: {keyId}")
            return False

        endpoint = f"{self.base_url}/iot/companies/{keyId}/exists"

        # 设置请求头
        headers = {
            "Accept": "*/*",
        }

        try:
            logger.info(f"检查向量库状态，keyId: {keyId}")
            # 发送GET请求
            response = self.session.get(
                endpoint,
                headers=headers,
                timeout=CONFIG["request_timeout"],
            )
            # 检查响应状态
            response.raise_for_status()
            # 从响应中提取exists字段
            result = response.json()
            exists = result.get("data", {}).get("exists", False)
            logger.info(f"向量库状态检查完成，keyId: {keyId}, exists: {exists}")
            return exists

        except requests.exceptions.Timeout:
            logger.error(f"检查向量库状态请求超时，keyId: {keyId}")
            return False
        except requests.RequestException as e:
            logger.error(f"检查向量库状态失败: {str(e)}")
            return False
        except Exception as e:
            logger.error(f"检查向量库状态发生未知异常: {str(e)}", exc_info=True)
            return False

    def query_devices_by_location(
        self,
        keyId: str,
        location: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        根据位置查询设备列表
        
        参数:
            keyId: 企业或项目的唯一标识符
            location: 设备位置（可选）
            
        返回:
            Dict[str, Any]: 包含设备列表的数据字典
        """
        logger = _ensure_logger()
        
        if not keyId or not isinstance(keyId, str):
            error_msg = "keyId参数是必需的且必须是字符串"
            logger.error(error_msg)
            return {
                "devices": [],
                "count": 0,
                "location_filter": location or ""
            }
        
        endpoint = f"{self.base_url}/iot/companies/{keyId}/devices"
        
        # 构建请求数据
        payload = {}
        if location:
            payload["location"] = location
        
        # 设置请求头
        headers = {
            "Content-Type": "application/json",
        }
        
        try:
            logger.info(f"查询设备列表，keyId: {keyId}, location: {location}")
            # 发送POST请求
            response = self.session.post(
                endpoint,
                headers=headers,
                data=json.dumps(payload),
                timeout=CONFIG["request_timeout"],
            )
            # 检查响应状态
            response.raise_for_status()
            # 解析JSON响应
            result = response.json()
            
            # 检查API返回的业务状态码
            if result.get("code") == 200:
                data = result.get("data", {})
                device_count = data.get("count", 0)
                logger.info(f"设备列表查询成功，返回设备数量: {device_count}")
                # 返回data部分
                return data
            else:
                error_msg = f"API返回业务错误: code={result.get('code')}, msg={result.get('msg')}"
                logger.error(error_msg)
                return {
                    "devices": [],
                    "count": 0,
                    "location_filter": location or "",
                    "error": error_msg
                }
        
        except requests.exceptions.Timeout:
            error_msg = f"查询设备列表请求超时，keyId: {keyId}"
            logger.error(error_msg)
            return {
                "devices": [],
                "count": 0,
                "location_filter": location or "",
                "error": error_msg
            }
        except requests.RequestException as e:
            error_msg = f"查询设备列表失败: {str(e)}"
            logger.error(error_msg)
            return {
                "devices": [],
                "count": 0,
                "location_filter": location or "",
                "error": error_msg
            }
        except Exception as e:
            error_msg = f"查询设备列表发生未知异常: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {
                "devices": [],
                "count": 0,
                "location_filter": location or "",
                "error": error_msg
            }

    def check_and_filter_devices(
        self, 
        device_list: List[Any], 
        device_op: Any
    ) -> Dict[str, Any]:
        """
        检查设备分数并过滤有效设备
        
        参数:
            device_list: 设备列表，格式为 [[device_info, score, score_details], ...]
            device_op: DeviceOperator实例，用于调用设备检查和预处理方法
            
        返回:
            Dict[str, Any]: 包含检查结果的字典
                - 如果有有效设备：返回有效设备列表
                - 如果无有效设备：返回候选设备列表和错误码
        """
        logger = _ensure_logger()
        logger.info("开始检查设备分数并过滤有效设备")
        logger.debug(f"输入设备列表数量: {len(device_list) if device_list else 0}")
        
        # 判断设备分数是否达标，给每个设备添加checkResult字段
        checked_device_list = []
        has_valid_device = False
        
        for device_item in device_list:
            # deviceList格式: [[device_info, score, score_details], ...]
            if isinstance(device_item, list) and len(device_item) >= 3:
                device_info, score, score_details = device_item[0], device_item[1], device_item[2]
                
                # 调用check_device_results_score方法检查分数
                check_result = device_op.check_device_results_score(score_details)
                
                # 将checkResult添加到device_info中
                if isinstance(device_info, dict):
                    device_info["checkResult"] = check_result.get("checkResult", False)
                    
                    # 检查是否有通过验证的设备
                    if device_info["checkResult"]:
                        has_valid_device = True
                
                # 重新构建device_item
                checked_device_list.append([device_info, score, score_details])
            else:
                # 如果格式不正确，保持原样但添加checkResult为False
                if isinstance(device_item, dict):
                    device_item["checkResult"] = False
                checked_device_list.append(device_item)
        
        # 如果没有任何设备通过验证，返回候选设备列表
        if not has_valid_device:
            logger.warning("匹配分数不够准确，返回候选设备列表")
            candidate_list = device_op.preprocess_results(checked_device_list)
            return {
                "code": 400, 
                "msg": "设备匹配分数不够准确,无法为用户智能操作设备，返回候选设备列表供用户选择; ", 
                "data": {
                    "candidates": candidate_list,
                    "total": len(candidate_list)
                },
                "is_candidate": True
            }
        
        # 过滤出checkResult为True的设备
        valid_devices = []
        for device_item in checked_device_list:
            if isinstance(device_item, list) and len(device_item) >= 1:
                device_info = device_item[0]
                if isinstance(device_info, dict) and device_info.get("checkResult", False):
                    valid_devices.append(device_item)
        
        logger.info(f"过滤完成，有效设备数量: {len(valid_devices)}")
        return {
            "valid_devices": valid_devices,
            "is_candidate": False
        }

    def __del__(self):
        """析构函数，关闭会话"""
        if hasattr(self, "session"):
            self.session.close()


# 使用示例
if __name__ == "__main__":
    # 测试代码只在直接运行此模块时执行，不在导入时执行
    # 以下代码已注释避免MCP服务器启动时执行
    pass
    
    # vector_service = VectorService(base_url="http://192.168.0.76:5002")

    # # 测试初始化向量存储
    # # init_result = vector_service.init_vector_store(
    # #     keyId="1945419433873575938",
    # # )
    # # print("初始化向量存储结果:", init_result)

    # # 测试查询向量420
    # # query_result = vector_service.query_vector(
    # #     **{
    # #         "keyId": "1932095424144715777",
    # #         "location": "灵泽办公区",
    # #         "device": "过道吊灯",
    # #         "operation": "开关 按键",
    # #         "top_k": 2,
    # #         "auto_create": True,
    # #     }
    # # )
    # # print("查询向量结果:", query_result)

    # # # 检查向量库状态
    # # check_result = vector_service.check_vector_store_status("1932095424144715777")
    # # logger.info(f"检查向量库状态结果: {check_result}")

    # # 测试搜索结果分析接口
    # # logger.info("=== 测试搜索结果分析接口 ===")
    # sample_search_results = [
    #     [
    #         {
    #             "id": "0899574c-ff51-4983-ae48-667cccc08e9c",
    #             "location": {
    #                 "key": "35",
    #                 "description": "灵泽展厅；灵泽展区"
    #             },
    #             "device": {
    #                 "key": "switch.zimi_cn_1121232402_dhkg05_on_p_2_1",
    #                 "description": "吊灯；灯；照明灯"
    #             },
    #             "operation": {
    #                 "key": "turn_off",
    #                 "description": "关闭；关"
    #             },
    #             "operation_params": [],
    #             "deviceType": "light"
    #         },
    #         0.9025000000000001,
    #         {
    #             "location_score": 0.95,
    #             "device_score": 0.75,
    #             "operation_score": 0.95,
    #             "operation_param_score": 1.0,
    #             "combined_score": 0.9025000000000001,
    #             "search_method": "location_first_strict"
    #         }
    #     ],
    #     [
    #         {
    #             "id": "76f71468-356b-4710-a7ea-da7ddac93fab",
    #             "location": {
    #                 "key": "35",
    #                 "description": "灵泽展厅；灵泽展区"
    #             },
    #             "device": {
    #                 "key": "climate.qjiang_cn_741362991_wb20",
    #                 "description": "空调；制冷设备"
    #             },
    #             "operation": {
    #                 "key": "turn_off",
    #                 "description": "关空调;关闭空调;关闭；关；闭空调；空调"
    #             },
    #             "operation_params": [],
    #             "deviceType": "airConditioner"
    #         },
    #         0.7150000000000001,
    #         {
    #             "location_score": 0.95,
    #             "device_score": 0.0,
    #             "operation_score": 0.95,
    #             "operation_param_score": 1.0,
    #             "combined_score": 0.7150000000000001,
    #             "search_method": "location_first_strict"
    #         }
    #     ]
    # ]
    
    # # analyze_result = vector_service.analyze_search_results(sample_search_results)
    # # logger.info(f"搜索结果分析结果: {analyze_result}")
