"""
对象同步模块
负责同步游戏对象的状态
"""

import time
from typing import Dict, Any, List, Optional
import threading
import copy

class ObjectSync:
    """
    对象同步器
    负责同步游戏对象的状态
    """
    
    def __init__(self, plugin):
        """
        初始化对象同步器
        
        Args:
            plugin: 网络同步插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 同步配置
        self.sync_config = {
            'sync_interval': 0.05,  # 50ms同步间隔
            'interpolation_time': 0.1,  # 100ms插值时间
            'extrapolation_limit': 0.2,  # 200ms外推限制
            'position_threshold': 0.01,  # 位置变化阈值
            'rotation_threshold': 0.1,   # 旋转变化阈值
            'scale_threshold': 0.01,     # 缩放变化阈值
            'enable_delta_compression': True,  # 启用增量压缩
            'enable_interpolation': True,  # 启用插值
            'enable_extrapolation': True,  # 启用外推
            'max_sync_distance': 100.0,    # 最大同步距离
            'sync_area_radius': 50.0       # 同步区域半径
        }
        
        # 同步对象管理
        self.sync_objects = {}  # 所有同步对象
        self.local_objects = {}  # 本地对象
        self.remote_objects = {}  # 远程对象
        
        # 同步状态
        self.sync_state = {
            'last_sync_time': 0.0,
            'objects_synced': 0,
            'sync_operations': 0,
            'interpolations': 0,
            'extrapolations': 0
        }
        
        # 插值数据
        self.interpolation_data = {}
        
        # 外推数据
        self.extrapolation_data = {}
        
        # 对象历史状态（用于插值）
        self.object_history = {}
        
        # 同步统计
        self.sync_stats = {
            'objects_registered': 0,
            'objects_synced': 0,
            'sync_data_sent': 0,
            'sync_data_received': 0,
            'interpolations': 0,
            'extrapolations': 0,
            'sync_errors': 0,
            'delta_compressions': 0
        }
        
        # 线程锁
        self.sync_lock = threading.RLock()
        
        # 回调函数
        self.sync_callbacks = {
            'object_registered': [],
            'object_unregistered': [],
            'sync_data_received': [],
            'object_updated': [],
            'sync_error': []
        }
        
        # 时间戳记录
        self.last_sync_update = 0.0
        self.last_interpolation_update = 0.0
        
        print("✓ 对象同步器已创建")
        
    def initialize(self) -> bool:
        """
        初始化对象同步器
        
        Returns:
            是否初始化成功
        """
        try:
            self.initialized = True
            print("✓ 对象同步器初始化完成")
            return True
            
        except Exception as e:
            print(f"✗ 对象同步器初始化失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def enable(self) -> bool:
        """
        启用对象同步器
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("✗ 对象同步器未初始化")
                return False
                
            self.enabled = True
            print("✓ 对象同步器已启用")
            return True
            
        except Exception as e:
            print(f"✗ 对象同步器启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用对象同步器"""
        try:
            self.enabled = False
            print("✓ 对象同步器已禁用")
            
        except Exception as e:
            print(f"✗ 对象同步器禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理对象同步器资源"""
        try:
            self.disable()
            self.sync_objects.clear()
            self.local_objects.clear()
            self.remote_objects.clear()
            self.interpolation_data.clear()
            self.extrapolation_data.clear()
            self.object_history.clear()
            self.sync_callbacks.clear()
            self.initialized = False
            print("✓ 对象同步器资源已清理")
            
        except Exception as e:
            print(f"✗ 对象同步器资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新对象同步器状态
        
        Args:
            dt: 时间增量
        """
        try:
            if not self.enabled:
                return
                
            current_time = time.time()
            self.last_sync_update = current_time
            
            # 执行同步操作
            if current_time - self.sync_state['last_sync_time'] >= self.sync_config['sync_interval']:
                self._perform_sync()
                self.sync_state['last_sync_time'] = current_time
                
            # 更新插值和外推
            self._update_interpolation(current_time)
            self._update_extrapolation(current_time)
            
        except Exception as e:
            print(f"✗ 对象同步器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _perform_sync(self):
        """执行同步操作"""
        try:
            # 收集需要同步的本地对象数据
            sync_data = {}
            
            with self.sync_lock:
                for obj_id, obj_data in self.local_objects.items():
                    # 检查对象是否需要同步
                    if self._should_sync_object(obj_id, obj_data):
                        sync_data[obj_id] = obj_data.copy()
                        
            # 发送同步数据
            if sync_data and self.plugin.network_manager:
                success = self.plugin.network_manager.send_sync_data(sync_data)
                if success:
                    self.sync_stats['sync_data_sent'] += 1
                    self.sync_stats['objects_synced'] += len(sync_data)
                    self.sync_state['sync_operations'] += 1
                else:
                    self.sync_stats['sync_errors'] += 1
                    
        except Exception as e:
            print(f"✗ 对象同步操作失败: {e}")
            self.sync_stats['sync_errors'] += 1
            
    def _should_sync_object(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        检查对象是否需要同步
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否需要同步
        """
        try:
            # 检查是否超出同步距离
            if not self._is_in_sync_range(obj_data):
                return False
                
            # 检查是否有显著变化
            if obj_id in self.sync_objects:
                old_data = self.sync_objects[obj_id]
                
                # 检查位置变化
                if 'position' in obj_data and 'position' in old_data:
                    pos_diff = self._calculate_distance(obj_data['position'], old_data['position'])
                    if pos_diff > self.sync_config['position_threshold']:
                        return True
                        
                # 检查旋转变化
                if 'rotation' in obj_data and 'rotation' in old_data:
                    rot_diff = self._calculate_rotation_difference(obj_data['rotation'], old_data['rotation'])
                    if rot_diff > self.sync_config['rotation_threshold']:
                        return True
                        
                # 检查缩放变化
                if 'scale' in obj_data and 'scale' in old_data:
                    scale_diff = self._calculate_scale_difference(obj_data['scale'], old_data['scale'])
                    if scale_diff > self.sync_config['scale_threshold']:
                        return True
                        
            else:
                # 新对象总是需要同步
                return True
                
            return False
            
        except Exception as e:
            print(f"✗ 对象同步检查失败: {e}")
            return True  # 出错时默认同步
            
    def _is_in_sync_range(self, obj_data: Dict[str, Any]) -> bool:
        """
        检查对象是否在同步范围内
        
        Args:
            obj_data: 对象数据
            
        Returns:
            是否在同步范围内
        """
        try:
            # 这里应该根据具体的游戏场景实现
            # 简单实现：假设所有对象都在同步范围内
            return True
        except Exception as e:
            print(f"✗ 同步范围检查失败: {e}")
            return True
            
    def _calculate_distance(self, pos1: List[float], pos2: List[float]) -> float:
        """
        计算两点间距离
        
        Args:
            pos1: 位置1
            pos2: 位置2
            
        Returns:
            距离
        """
        try:
            if len(pos1) >= 3 and len(pos2) >= 3:
                dx = pos1[0] - pos2[0]
                dy = pos1[1] - pos2[1]
                dz = pos1[2] - pos2[2]
                return (dx*dx + dy*dy + dz*dz) ** 0.5
            elif len(pos1) >= 2 and len(pos2) >= 2:
                dx = pos1[0] - pos2[0]
                dy = pos1[1] - pos2[1]
                return (dx*dx + dy*dy) ** 0.5
            else:
                return 0.0
        except Exception as e:
            print(f"✗ 距离计算失败: {e}")
            return 0.0
            
    def _calculate_rotation_difference(self, rot1: List[float], rot2: List[float]) -> float:
        """
        计算旋转差异
        
        Args:
            rot1: 旋转1
            rot2: 旋转2
            
        Returns:
            旋转差异
        """
        try:
            # 简单实现：计算欧拉角差异
            diff = 0.0
            for i in range(min(len(rot1), len(rot2))):
                diff += abs(rot1[i] - rot2[i])
            return diff
        except Exception as e:
            print(f"✗ 旋转差异计算失败: {e}")
            return 0.0
            
    def _calculate_scale_difference(self, scale1: List[float], scale2: List[float]) -> float:
        """
        计算缩放差异
        
        Args:
            scale1: 缩放1
            scale2: 缩放2
            
        Returns:
            缩放差异
        """
        try:
            # 简单实现：计算缩放差异
            diff = 0.0
            for i in range(min(len(scale1), len(scale2))):
                diff += abs(scale1[i] - scale2[i])
            return diff
        except Exception as e:
            print(f"✗ 缩放差异计算失败: {e}")
            return 0.0
            
    def _update_interpolation(self, current_time: float):
        """
        更新插值
        
        Args:
            current_time: 当前时间
        """
        try:
            if not self.sync_config['enable_interpolation']:
                return
                
            updated_count = 0
            with self.sync_lock:
                for obj_id, interp_data in self.interpolation_data.items():
                    if self._perform_object_interpolation(obj_id, interp_data, current_time):
                        updated_count += 1
                        
            self.sync_stats['interpolations'] += updated_count
            
        except Exception as e:
            print(f"✗ 插值更新失败: {e}")
            
    def _perform_object_interpolation(self, obj_id: str, interp_data: Dict[str, Any], current_time: float) -> bool:
        """
        执行对象插值
        
        Args:
            obj_id: 对象ID
            interp_data: 插值数据
            current_time: 当前时间
            
        Returns:
            是否插值成功
        """
        try:
            start_time = interp_data.get('start_time', current_time)
            end_time = interp_data.get('end_time', current_time)
            duration = end_time - start_time
            
            if duration > 0:
                progress = (current_time - start_time) / duration
                progress = max(0.0, min(1.0, progress))  # 限制在0-1之间
                
                # 线性插值位置
                if 'start_position' in interp_data and 'end_position' in interp_data:
                    start_pos = interp_data['start_position']
                    end_pos = interp_data['end_position']
                    current_pos = [
                        start_pos[i] + (end_pos[i] - start_pos[i]) * progress
                        for i in range(min(len(start_pos), len(end_pos)))
                    ]
                    
                    # 更新对象位置
                    if obj_id in self.remote_objects:
                        self.remote_objects[obj_id]['position'] = current_pos
                        
                # 球面插值旋转（简化为线性插值）
                if 'start_rotation' in interp_data and 'end_rotation' in interp_data:
                    start_rot = interp_data['start_rotation']
                    end_rot = interp_data['end_rotation']
                    current_rot = [
                        start_rot[i] + (end_rot[i] - start_rot[i]) * progress
                        for i in range(min(len(start_rot), len(end_rot)))
                    ]
                    
                    # 更新对象旋转
                    if obj_id in self.remote_objects:
                        self.remote_objects[obj_id]['rotation'] = current_rot
                        
                # 线性插值缩放
                if 'start_scale' in interp_data and 'end_scale' in interp_data:
                    start_scale = interp_data['start_scale']
                    end_scale = interp_data['end_scale']
                    current_scale = [
                        start_scale[i] + (end_scale[i] - start_scale[i]) * progress
                        for i in range(min(len(start_scale), len(end_scale)))
                    ]
                    
                    # 更新对象缩放
                    if obj_id in self.remote_objects:
                        self.remote_objects[obj_id]['scale'] = current_scale
                        
                return True
            else:
                return False
                
        except Exception as e:
            print(f"✗ 对象插值失败: {e}")
            return False
            
    def _update_extrapolation(self, current_time: float):
        """
        更新外推
        
        Args:
            current_time: 当前时间
        """
        try:
            if not self.sync_config['enable_extrapolation']:
                return
                
            updated_count = 0
            with self.sync_lock:
                for obj_id, extrap_data in self.extrapolation_data.items():
                    if self._perform_object_extrapolation(obj_id, extrap_data, current_time):
                        updated_count += 1
                        
            self.sync_stats['extrapolations'] += updated_count
            
        except Exception as e:
            print(f"✗ 外推更新失败: {e}")
            
    def _perform_object_extrapolation(self, obj_id: str, extrap_data: Dict[str, Any], current_time: float) -> bool:
        """
        执行对象外推
        
        Args:
            obj_id: 对象ID
            extrap_data: 外推数据
            current_time: 当前时间
            
        Returns:
            是否外推成功
        """
        try:
            last_update_time = extrap_data.get('last_update_time', current_time)
            time_diff = current_time - last_update_time
            
            # 检查是否超出外推限制
            if time_diff > self.sync_config['extrapolation_limit']:
                return False
                
            # 基于速度的外推
            if 'position' in extrap_data and 'velocity' in extrap_data:
                position = extrap_data['position']
                velocity = extrap_data['velocity']
                
                # 计算外推位置
                extrapolated_pos = [
                    position[i] + velocity[i] * time_diff
                    for i in range(min(len(position), len(velocity)))
                ]
                
                # 更新对象位置
                if obj_id in self.remote_objects:
                    self.remote_objects[obj_id]['position'] = extrapolated_pos
                    
            return True
            
        except Exception as e:
            print(f"✗ 对象外推失败: {e}")
            return False
            
    def register_object(self, obj_id: str, obj_data: Dict[str, Any], is_local: bool = True) -> bool:
        """
        注册同步对象
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            is_local: 是否为本地对象
            
        Returns:
            是否注册成功
        """
        try:
            with self.sync_lock:
                # 存储对象数据
                self.sync_objects[obj_id] = obj_data.copy()
                
                if is_local:
                    self.local_objects[obj_id] = obj_data.copy()
                else:
                    self.remote_objects[obj_id] = obj_data.copy()
                    
                # 初始化对象历史
                self.object_history[obj_id] = {
                    'states': [obj_data.copy()],
                    'timestamps': [time.time()]
                }
                
                # 更新统计信息
                self.sync_stats['objects_registered'] += 1
                
            # 触发对象注册回调
            self._trigger_sync_callback('object_registered', {
                'object_id': obj_id,
                'is_local': is_local,
                'data': obj_data
            })
            
            print(f"✓ 对象已注册: {obj_id} ({'本地' if is_local else '远程'})")
            return True
            
        except Exception as e:
            print(f"✗ 对象注册失败: {e}")
            self.sync_stats['sync_errors'] += 1
            return False
            
    def unregister_object(self, obj_id: str) -> bool:
        """
        注销同步对象
        
        Args:
            obj_id: 对象ID
            
        Returns:
            是否注销成功
        """
        try:
            with self.sync_lock:
                # 从各个字典中移除对象
                if obj_id in self.sync_objects:
                    del self.sync_objects[obj_id]
                    
                if obj_id in self.local_objects:
                    del self.local_objects[obj_id]
                    
                if obj_id in self.remote_objects:
                    del self.remote_objects[obj_id]
                    
                if obj_id in self.interpolation_data:
                    del self.interpolation_data[obj_id]
                    
                if obj_id in self.extrapolation_data:
                    del self.extrapolation_data[obj_id]
                    
                if obj_id in self.object_history:
                    del self.object_history[obj_id]
                    
            # 触发对象注销回调
            self._trigger_sync_callback('object_unregistered', {
                'object_id': obj_id
            })
            
            print(f"✓ 对象已注销: {obj_id}")
            return True
            
        except Exception as e:
            print(f"✗ 对象注销失败: {e}")
            self.sync_stats['sync_errors'] += 1
            return False
            
    def update_object(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        更新对象数据
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否更新成功
        """
        try:
            with self.sync_lock:
                # 更新同步对象
                if obj_id in self.sync_objects:
                    self.sync_objects[obj_id].update(obj_data)
                    
                # 更新本地对象
                if obj_id in self.local_objects:
                    self.local_objects[obj_id].update(obj_data)
                    
                # 添加到对象历史（用于插值）
                if obj_id in self.object_history:
                    history = self.object_history[obj_id]
                    history['states'].append(obj_data.copy())
                    history['timestamps'].append(time.time())
                    
                    # 保持历史记录大小
                    if len(history['states']) > 10:  # 保持最近10个状态
                        history['states'].pop(0)
                        history['timestamps'].pop(0)
                        
            # 触发对象更新回调
            self._trigger_sync_callback('object_updated', {
                'object_id': obj_id,
                'data': obj_data
            })
            
            return True
            
        except Exception as e:
            print(f"✗ 对象更新失败: {e}")
            self.sync_stats['sync_errors'] += 1
            return False
            
    def sync_object(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        同步对象
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否同步成功
        """
        try:
            if not self.enabled:
                print("✗ 对象同步器未启用")
                return False
                
            # 更新对象数据
            success = self.update_object(obj_id, obj_data)
            
            if success:
                self.sync_stats['objects_synced'] += 1
                return True
            else:
                self.sync_stats['sync_errors'] += 1
                return False
                
        except Exception as e:
            print(f"✗ 对象同步失败: {e}")
            self.sync_stats['sync_errors'] += 1
            return False
            
    def receive_sync_data(self, obj_id: str, obj_data: Dict[str, Any], client_id: str = None) -> bool:
        """
        接收同步数据
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            client_id: 客户端ID（可选）
            
        Returns:
            是否接收成功
        """
        try:
            with self.sync_lock:
                # 存储远程对象数据
                self.remote_objects[obj_id] = obj_data.copy()
                self.sync_objects[obj_id] = obj_data.copy()
                
                # 设置插值数据
                current_time = time.time()
                if obj_id in self.interpolation_data:
                    # 更新现有插值数据
                    interp_data = self.interpolation_data[obj_id]
                    interp_data['start_time'] = current_time
                    interp_data['end_time'] = current_time + self.sync_config['interpolation_time']
                    interp_data['start_position'] = interp_data.get('end_position', obj_data.get('position', [0, 0, 0]))
                    interp_data['end_position'] = obj_data.get('position', [0, 0, 0])
                    interp_data['start_rotation'] = interp_data.get('end_rotation', obj_data.get('rotation', [0, 0, 0]))
                    interp_data['end_rotation'] = obj_data.get('rotation', [0, 0, 0])
                    interp_data['start_scale'] = interp_data.get('end_scale', obj_data.get('scale', [1, 1, 1]))
                    interp_data['end_scale'] = obj_data.get('scale', [1, 1, 1])
                else:
                    # 创建新的插值数据
                    self.interpolation_data[obj_id] = {
                        'start_time': current_time,
                        'end_time': current_time + self.sync_config['interpolation_time'],
                        'start_position': obj_data.get('position', [0, 0, 0]),
                        'end_position': obj_data.get('position', [0, 0, 0]),
                        'start_rotation': obj_data.get('rotation', [0, 0, 0]),
                        'end_rotation': obj_data.get('rotation', [0, 0, 0]),
                        'start_scale': obj_data.get('scale', [1, 1, 1]),
                        'end_scale': obj_data.get('scale', [1, 1, 1])
                    }
                    
                # 设置外推数据
                self.extrapolation_data[obj_id] = {
                    'position': obj_data.get('position', [0, 0, 0]),
                    'velocity': obj_data.get('velocity', [0, 0, 0]),
                    'last_update_time': current_time
                }
                
                # 更新对象历史
                if obj_id in self.object_history:
                    history = self.object_history[obj_id]
                    history['states'].append(obj_data.copy())
                    history['timestamps'].append(current_time)
                    
                    # 保持历史记录大小
                    if len(history['states']) > 10:
                        history['states'].pop(0)
                        history['timestamps'].pop(0)
                else:
                    self.object_history[obj_id] = {
                        'states': [obj_data.copy()],
                        'timestamps': [current_time]
                    }
                    
            # 更新统计信息
            self.sync_stats['sync_data_received'] += 1
            
            # 触发同步数据接收回调
            self._trigger_sync_callback('sync_data_received', {
                'object_id': obj_id,
                'data': obj_data,
                'client_id': client_id
            })
            
            return True
            
        except Exception as e:
            print(f"✗ 同步数据接收失败: {e}")
            self.sync_stats['sync_errors'] += 1
            return False
            
    def get_object_data(self, obj_id: str) -> Optional[Dict[str, Any]]:
        """
        获取对象数据
        
        Args:
            obj_id: 对象ID
            
        Returns:
            对象数据或None
        """
        try:
            with self.sync_lock:
                return self.sync_objects.get(obj_id, {}).copy()
        except Exception as e:
            print(f"✗ 对象数据获取失败: {e}")
            return None
            
    def get_local_objects(self) -> Dict[str, Dict[str, Any]]:
        """
        获取所有本地对象
        
        Returns:
            本地对象字典
        """
        try:
            with self.sync_lock:
                return {k: v.copy() for k, v in self.local_objects.items()}
        except Exception as e:
            print(f"✗ 本地对象获取失败: {e}")
            return {}
            
    def get_remote_objects(self) -> Dict[str, Dict[str, Any]]:
        """
        获取所有远程对象
        
        Returns:
            远程对象字典
        """
        try:
            with self.sync_lock:
                return {k: v.copy() for k, v in self.remote_objects.items()}
        except Exception as e:
            print(f"✗ 远程对象获取失败: {e}")
            return {}
            
    def get_sync_stats(self) -> Dict[str, Any]:
        """
        获取同步统计信息
        
        Returns:
            同步统计字典
        """
        return self.sync_stats.copy()
        
    def reset_sync_stats(self):
        """重置同步统计信息"""
        try:
            self.sync_stats = {
                'objects_registered': 0,
                'objects_synced': 0,
                'sync_data_sent': 0,
                'sync_data_received': 0,
                'interpolations': 0,
                'extrapolations': 0,
                'sync_errors': 0,
                'delta_compressions': 0
            }
            print("✓ 对象同步统计信息已重置")
        except Exception as e:
            print(f"✗ 对象同步统计信息重置失败: {e}")
            
    def set_sync_config(self, config: Dict[str, Any]) -> bool:
        """
        设置同步配置
        
        Args:
            config: 同步配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.sync_config.update(config)
            print(f"✓ 同步配置已更新: {self.sync_config}")
            return True
        except Exception as e:
            print(f"✗ 同步配置设置失败: {e}")
            return False
            
    def get_sync_config(self) -> Dict[str, Any]:
        """
        获取同步配置
        
        Returns:
            同步配置字典
        """
        return self.sync_config.copy()
        
    def _trigger_sync_callback(self, callback_type: str, data: Dict[str, Any]):
        """
        触发同步回调
        
        Args:
            callback_type: 回调类型
            data: 回调数据
        """
        try:
            if callback_type in self.sync_callbacks:
                for callback in self.sync_callbacks[callback_type]:
                    try:
                        callback(data)
                    except Exception as e:
                        print(f"✗ 同步回调执行失败: {e}")
        except Exception as e:
            print(f"✗ 同步回调触发失败: {e}")
            
    def register_sync_callback(self, callback_type: str, callback: callable):
        """
        注册同步回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.sync_callbacks:
                self.sync_callbacks[callback_type].append(callback)
                print(f"✓ 同步回调已注册: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 同步回调注册失败: {e}")
            
    def unregister_sync_callback(self, callback_type: str, callback: callable):
        """
        注销同步回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.sync_callbacks:
                if callback in self.sync_callbacks[callback_type]:
                    self.sync_callbacks[callback_type].remove(callback)
                    print(f"✓ 同步回调已注销: {callback_type}")
        except Exception as e:
            print(f"✗ 同步回调注销失败: {e}")