#!/usr/bin/env python3
import os
import sys
import json
from typing import List, Dict, Any, Optional, Tuple

import logging

import rospy # type: ignore
import threading
import time
from std_msgs.msg import String # type: ignore
from sensor_msgs.msg import Image as Sensor_Image # type: ignore
from cv_bridge import CvBridge, CvBridgeError # pyright: ignore[reportMissingImports]
import cv2
import numpy as np

import magic  # 用于识别文件类型（辅助文件搜索工具）
import base64
import asyncio

# 配置日志记录器
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

# ------------------------------
# 多模态处理器
# ------------------------------
class MultimodalProcessor:
    """处理多模态输入输出，实现不同类型数据的转换和处理"""
    
    def __init__(self):
        self.bridge = CvBridge()
        self.supported_image_formats = ['bgr8', 'rgb8', 'mono8']
        
    def ros_image2dict(self, image_msg: Sensor_Image) -> Optional[Dict[str, Any]]:
        """
        将ROS图像消息转换为字典格式，便于在上下文中存储
        
        参数:
            image_msg: ROS的Image消息
            
        返回:
            包含图像信息的字典，或None(转换失败时)
        """
        try:
            # 尝试转换为OpenCV格式
            if image_msg.encoding in self.supported_image_formats:
                cv_image = self.bridge.imgmsg_to_cv2(image_msg, desired_encoding=image_msg.encoding)
            else:
                # 尝试默认转换
                cv_image = self.bridge.imgmsg_to_cv2(image_msg)
                logger.warning(f"转换不支持的图像编码: {image_msg.encoding}")
                
            # 图像预处理：调整大小以减少数据量
            max_dim = 300
            h, w = cv_image.shape[:2]
            if max(h, w) > max_dim:
                scale = max_dim / max(h, w)
                cv_image = cv2.resize(
                    cv_image, 
                    (int(w * scale), int(h * scale)),
                    interpolation=cv2.INTER_AREA
                )
                
            # 转换为JPEG并编码为base64
            encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 80]
            _, buffer = cv2.imencode('.jpg', cv_image, encode_param)
            img_base64 = base64.b64encode(buffer).decode('utf-8')
            
            return {
                "type": "image",
                "format": "JPRG_BASE64",
                "data": img_base64,
                "width": cv_image.shape[1],
                "height": cv_image.shape[0],
                "original_encoding": image_msg.encoding,
                "timestamp": image_msg.header.stamp.to_sec()
            }
            
        except CvBridgeError as e:
            logger.error(f"CV桥接错误: {str(e)}")
        except Exception as e:
            logger.error(f"图像处理错误: {str(e)}")
        return None
    
    def dict2ros_image(self, image_dict: Dict[str, Any]) -> Optional[Sensor_Image]:
        """
        将图像字典转换回ROS Image消息
        
        参数:
            image_dict: 包含图像信息的字典
            
        返回:
            ROS Image消息，或None(转换失败时)
        """
        try:
            if image_dict.get("type") != "image" or "data" not in image_dict:
                logger.error("无效的图像字典格式")
                return None
                
            # 解码base64数据
            img_data = base64.b64decode(image_dict["data"])
            np_arr = np.frombuffer(img_data, np.uint8)
            cv_image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
            
            # 转换为ROS Image消息
            return self.bridge.cv2_to_imgmsg(cv_image, encoding="bgr8")
            
        except Exception as e:
            logger.error(f"图像转换为ROS消息失败: {str(e)}")
            return None
    
    def process_text(self, text: str) -> Dict[str, Any]:
        """
        处理文本输入，进行基本的清洗和格式化
        
        参数:
            text: 输入文本
            
        返回:
            包含处理后文本的字典
        """
        # 基本文本清洗
        cleaned_text = text.strip()
        # 移除多余空行
        cleaned_text = "\n".join([line.strip() for line in cleaned_text.splitlines() if line.strip()])
        
        return {
            "type": "text",
            "data": cleaned_text,
            "length": len(cleaned_text),
            "timestamp": time.time()
        }