
#!/usr/bin/env python3

import os
import sys
import io
from typing import List, Dict, Any, Optional, Tuple, Union

import logging
from pathlib import Path

from PIL import Image as PIL_Image
import base64
import numpy as np

# Removed ROS dependencies
# import rospy # type: ignore
# 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 # type: ignore
import cv2


# 获取当前脚本的路径（Path 对象）
current_script = Path(__file__).resolve()
# 向上两级找到项目根目录（根据实际结构调整层级）
project_root = current_script.parents[2]  # parents[0] 是当前目录，parents[1] 是父目录，以此类推

# print("project_root: ",project_root)

#添加到搜索路径
sys.path.append(str(project_root))

#查看系统环境
# print("sys path:",sys.path)

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


# 图像处理工具函数
def decode_base64_image(base64_str: str) -> PIL_Image.Image:
    """将base64编码的字符串解码为PIL图像"""
    try:
        image_data = base64.b64decode(base64_str)
        image = PIL_Image.open(io.BytesIO(image_data)).convert("RGB")
        return image
    except Exception as e:
        raise ValueError(f"图像解码失败: {str(e)}")

def preprocess_image(image: PIL_Image.Image, need_resize: bool= False, target_size: tuple = (336, 336)) -> np.ndarray:
    """预处理图像以适应模型输入要求"""
    # 调整大小
    if need_resize:
        image = image.resize(target_size, PIL_Image.Resampling.LANCZOS)
    # 转换为numpy数组
    image_np = np.array(image, dtype=np.float32)
    # 归一化（根据模型要求调整）
    image_np = image_np / 255.0
    return image_np

from io import BytesIO
def PIL_image_to_base64( image_path: Optional[str] = None, image: Optional[PIL_Image.Image] = None) :
    """
    将图像转换为base64编码
    
    参数:
        image_path: 图像文件路径
        image: PIL Image对象
        
    返回:
        base64编码字符串
    """
    if image is None:
        if not image_path:
            raise ValueError("必须提供图像路径或图像对象")
        image = PIL_Image.open(image_path).convert("RGB")
    
    # 转换为JPEG并编码
    buffered = BytesIO()
    image.save(buffered, format="JPEG", quality=90)
    return base64.b64encode(buffered.getvalue()).decode('utf-8')

# def ros_image2pil_image(self, ros_image_msg:Sensor_Image,supported_image_formats):
#     """回调函数：将ROS Image转为PIL Image并处理"""
#     try:
#         bridge_cv = CvBridge()
#         # 1. 将ROS Image消息转为OpenCV格式（默认BGR8编码）
#         # 若图像编码不同（如rgb8），需指定格式：bridge.imgmsg_to_cv2(ros_image_msg, "rgb8")
#         # 尝试转换为OpenCV格式
#         if ros_image_msg.encoding in supported_image_formats:
#             cv_image = bridge_cv.imgmsg_to_cv2(ros_image_msg, desired_encoding=ros_image_msg.encoding)
#         else:
#             # 尝试默认转换
#             cv_image = bridge_cv.imgmsg_to_cv2(ros_image_msg)
#             logger.warning(f"转换不支持的图像编码: {ros_image_msg.encoding}")


#         # 2. OpenCV默认是BGR格式，转为PIL需要的RGB格式
#         rgb_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)

#         # 3. 转为PIL Image格式
#         pil_image = PIL_Image.fromarray(rgb_image)

#         # 此处可添加对PIL Image的处理（如显示、保存等）
#         rospy.loginfo(f"转换成功：PIL Image尺寸 {pil_image.size}")
#         return pil_image
#         # 示例：显示图像（需要PIL的显示支持）
#         # pil_image.show()

#     except CvBridgeError as e:
#         rospy.logerr(f"转换失败：{e}")
#     except Exception as e:
#         rospy.logerr(f"处理错误：{e}")
    

# def ros_image2dict(self, image_msg: Sensor_Image,
#                       supported_image_formats=['bgr8', 'rgb8', 'mono8'],
#                       max_dim:int =2000) :
#     """
#     将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}")
            
#         # 图像预处理：调整大小以减少数据量
#         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": "jpg",
#             "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 PIL_image_to_base64_sizelmt(image_path:Optional[str]=None,image:Optional[PIL_Image.Image] = None, 
                                need_size_lmt:bool= False, max_size:tuple=(800, 800), quality:float=90):
    """处理图像并转换为Base64编码"""
    try:
        if image is None:
            if not image_path:
                raise ValueError("必须提供图像路径或图像对象")
            # with PIL_Image.open(image_path) as image:
            image = PIL_Image.open(image_path) #.convert("RGB")

        if need_size_lmt:
            # 缩放图像以控制大小（避免Token超限）
            image.thumbnail(max_size,PIL_Image.Resampling.LANCZOS)
    
        # 处理透明通道（Qwen2.5-VL对RGBA支持有限）
        if image.mode in ('RGBA', 'LA'):
            background = PIL_Image.new(image.mode[:-1], image.size, (255, 255, 255))
            background.paste(image, mask=image.split()[-1])
            image = background
        elif image.mode == 'P':
            image = image.convert('RGB')

        elif image.mode != 'RGB':
            image = image.convert('RGB')
            
        # 保存为JPEG并编码为Base64
        buffer = io.BytesIO()
        image.save(buffer, format="JPEG", quality=quality)
        return base64.b64encode(buffer.getvalue()).decode('utf-8')

        # buffered = BytesIO()
        # image.save(buffered, format="JPEG", quality=90)
        # return base64.b64encode(buffered.getvalue()).decode('utf-8')

    except Exception as e:
        print(f"图像处理错误: {str(e)}")
        return None
