"""
同步管理器模块
负责管理网络同步的核心功能
"""

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

class SyncManager:
    """
    同步管理器
    负责管理网络同步的核心功能
    """
    
    def __init__(self, plugin):
        """
        初始化同步管理器
        
        Args:
            plugin: 网络同步插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 同步配置
        self.sync_config = {
            'sync_rate': 20,  # 每秒同步频率
            'interpolation_rate': 60,  # 插值更新频率
            'extrapolation_limit': 0.1,  # 外推限制（秒）
            'sync_distance_threshold': 0.01,  # 同步距离阈值
            'sync_rotation_threshold': 0.1,  # 同步旋转阈值
            'sync_scale_threshold': 0.01,  # 同步缩放阈值
            'enable_delta_compression': True,  # 启用增量压缩
            'enable_state_filtering': True,  # 启用状态过滤
            'max_sync_objects': 1000,  # 最大同步对象数
            'sync_area_radius': 100.0  # 同步区域半径
        }
        
        # 同步对象管理
        self.sync_objects = {}  # 所有同步对象
        self.local_objects = {}  # 本地对象
        self.remote_objects = {}  # 远程对象
        self.sync_groups = {}  # 同步组
        
        # 同步状态
        self.sync_state = {
            'last_sync_time': 0.0,
            'last_interpolation_time': 0.0,
            'sync_objects_count': 0,
            'local_objects_count': 0,
            'remote_objects_count': 0,
            'sync_groups_count': 0
        }
        
        # 插值管理
        self.interpolation_data = {}
        
        # 外推管理
        self.extrapolation_data = {}
        
        # 同步统计
        self.sync_stats = {
            'objects_synced': 0,
            'sync_operations': 0,
            'interpolations': 0,
            'extrapolations': 0,
            'sync_errors': 0,
            'delta_compressions': 0
        }
        
        # 线程管理
        self.sync_thread = None
        self.interpolation_thread = None
        self.running = False
        
        # 回调函数
        self.sync_callbacks = {
            'object_synced': [],
            'sync_error': [],
            'interpolation_updated': [],
            'extrapolation_updated': []
        }
        
        # 时间戳记录
        self.last_update_time = 0.0
        self.last_sync_check = 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
            self.running = True
            
            # 启动同步线程
            self.sync_thread = threading.Thread(target=self._sync_loop, daemon=True)
            self.sync_thread.start()
            
            # 启动插值线程
            self.interpolation_thread = threading.Thread(target=self._interpolation_loop, daemon=True)
            self.interpolation_thread.start()
            
            print("✓ 同步管理器已启用")
            return True
            
        except Exception as e:
            print(f"✗ 同步管理器启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用同步管理器"""
        try:
            self.enabled = False
            self.running = False
            
            # 等待线程结束
            if self.sync_thread and self.sync_thread.is_alive():
                self.sync_thread.join(timeout=1.0)
                
            if self.interpolation_thread and self.interpolation_thread.is_alive():
                self.interpolation_thread.join(timeout=1.0)
                
            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.sync_groups.clear()
            self.interpolation_data.clear()
            self.extrapolation_data.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_update_time = current_time
            
        except Exception as e:
            print(f"✗ 同步管理器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _sync_loop(self):
        """同步循环线程"""
        try:
            sync_interval = 1.0 / self.sync_config['sync_rate']
            
            while self.running:
                if self.enabled:
                    current_time = time.time()
                    if current_time - self.sync_state['last_sync_time'] >= sync_interval:
                        self._perform_sync()
                        self.sync_state['last_sync_time'] = current_time
                        
                time.sleep(0.001)  # 1ms
                
        except Exception as e:
            print(f"✗ 同步循环失败: {e}")
            
    def _interpolation_loop(self):
        """插值循环线程"""
        try:
            interpolation_interval = 1.0 / self.sync_config['interpolation_rate']
            
            while self.running:
                if self.enabled:
                    current_time = time.time()
                    if current_time - self.sync_state['last_interpolation_time'] >= interpolation_interval:
                        self._perform_interpolation()
                        self.sync_state['last_interpolation_time'] = current_time
                        
                time.sleep(0.001)  # 1ms
                
        except Exception as e:
            print(f"✗ 插值循环失败: {e}")
            
    def _perform_sync(self):
        """执行同步操作"""
        try:
            # 收集需要同步的对象
            objects_to_sync = self._collect_sync_objects()
            
            # 执行同步
            for obj_id, obj_data in objects_to_sync.items():
                if self.plugin.object_sync:
                    success = self.plugin.object_sync.sync_object(obj_id, obj_data)
                    if success:
                        self.sync_stats['objects_synced'] += 1
                        self._trigger_sync_callback('object_synced', {
                            'object_id': obj_id,
                            'object_data': obj_data
                        })
                    else:
                        self.sync_stats['sync_errors'] += 1
                        self._trigger_sync_callback('sync_error', {
                            'object_id': obj_id,
                            'error': 'Sync failed'
                        })
                        
            self.sync_stats['sync_operations'] += 1
            
        except Exception as e:
            print(f"✗ 同步操作失败: {e}")
            self.sync_stats['sync_errors'] += 1
            
    def _perform_interpolation(self):
        """执行插值操作"""
        try:
            current_time = time.time()
            
            # 更新插值数据
            for obj_id, interp_data in self.interpolation_data.items():
                if self._update_interpolation(obj_id, interp_data, current_time):
                    self.sync_stats['interpolations'] += 1
                    self._trigger_sync_callback('interpolation_updated', {
                        'object_id': obj_id,
                        'interpolation_data': interp_data
                    })
                    
            # 更新外推数据
            for obj_id, extrap_data in self.extrapolation_data.items():
                if self._update_extrapolation(obj_id, extrap_data, current_time):
                    self.sync_stats['extrapolations'] += 1
                    self._trigger_sync_callback('extrapolation_updated', {
                        'object_id': obj_id,
                        'extrapolation_data': extrap_data
                    })
                    
        except Exception as e:
            print(f"✗ 插值操作失败: {e}")
            
    def _collect_sync_objects(self) -> Dict[str, Any]:
        """
        收集需要同步的对象
        
        Returns:
            需要同步的对象字典
        """
        try:
            objects_to_sync = {}
            
            # 收集本地对象中需要同步的
            for obj_id, obj_data in self.local_objects.items():
                # 检查对象是否需要同步（基于变化阈值）
                if self._should_sync_object(obj_id, obj_data):
                    objects_to_sync[obj_id] = obj_data
                    
            return objects_to_sync
            
        except Exception as e:
            print(f"✗ 同步对象收集失败: {e}")
            return {}
            
    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_area(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['sync_distance_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['sync_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['sync_scale_threshold']:
                        return True
                        
            else:
                # 新对象总是需要同步
                return True
                
            return False
            
        except Exception as e:
            print(f"✗ 对象同步检查失败: {e}")
            return True  # 出错时默认同步
            
    def _is_in_sync_area(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, 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 obj_id in self.remote_objects:
                    obj = self.remote_objects[obj_id]
                    # 这里应该实际更新对象的位置、旋转等属性
                    # 由于是模拟实现，只打印信息
                    pass
                    
                return True
            else:
                return False
                
        except Exception as e:
            print(f"✗ 插值更新失败: {e}")
            return False
            
    def _update_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']:
                # 在外推限制内，可以进行外推
                # 这里应该实际更新对象的状态
                # 由于是模拟实现，只打印信息
                pass
                return True
            else:
                return False
                
        except Exception as e:
            print(f"✗ 外推更新失败: {e}")
            return False
            
    def register_local_object(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        注册本地对象
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否注册成功
        """
        try:
            self.local_objects[obj_id] = obj_data
            self.sync_objects[obj_id] = obj_data
            self.sync_state['local_objects_count'] = len(self.local_objects)
            self.sync_state['sync_objects_count'] = len(self.sync_objects)
            
            print(f"✓ 本地对象已注册: {obj_id}")
            return True
            
        except Exception as e:
            print(f"✗ 本地对象注册失败: {e}")
            return False
            
    def unregister_local_object(self, obj_id: str) -> bool:
        """
        注销本地对象
        
        Args:
            obj_id: 对象ID
            
        Returns:
            是否注销成功
        """
        try:
            if obj_id in self.local_objects:
                del self.local_objects[obj_id]
                
            if obj_id in self.sync_objects:
                del self.sync_objects[obj_id]
                
            self.sync_state['local_objects_count'] = len(self.local_objects)
            self.sync_state['sync_objects_count'] = len(self.sync_objects)
            
            print(f"✓ 本地对象已注销: {obj_id}")
            return True
            
        except Exception as e:
            print(f"✗ 本地对象注销失败: {e}")
            return False
            
    def register_remote_object(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        注册远程对象
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否注册成功
        """
        try:
            self.remote_objects[obj_id] = obj_data
            self.sync_objects[obj_id] = obj_data
            self.sync_state['remote_objects_count'] = len(self.remote_objects)
            self.sync_state['sync_objects_count'] = len(self.sync_objects)
            
            print(f"✓ 远程对象已注册: {obj_id}")
            return True
            
        except Exception as e:
            print(f"✗ 远程对象注册失败: {e}")
            return False
            
    def unregister_remote_object(self, obj_id: str) -> bool:
        """
        注销远程对象
        
        Args:
            obj_id: 对象ID
            
        Returns:
            是否注销成功
        """
        try:
            if obj_id in self.remote_objects:
                del self.remote_objects[obj_id]
                
            if obj_id in self.sync_objects:
                del self.sync_objects[obj_id]
                
            self.sync_state['remote_objects_count'] = len(self.remote_objects)
            self.sync_state['sync_objects_count'] = len(self.sync_objects)
            
            print(f"✓ 远程对象已注销: {obj_id}")
            return True
            
        except Exception as e:
            print(f"✗ 远程对象注销失败: {e}")
            return False
            
    def update_object_data(self, obj_id: str, obj_data: Dict[str, Any]) -> bool:
        """
        更新对象数据
        
        Args:
            obj_id: 对象ID
            obj_data: 对象数据
            
        Returns:
            是否更新成功
        """
        try:
            if obj_id in self.local_objects:
                self.local_objects[obj_id].update(obj_data)
                
            if obj_id in self.sync_objects:
                self.sync_objects[obj_id].update(obj_data)
                
            return True
            
        except Exception as e:
            print(f"✗ 对象数据更新失败: {e}")
            return False
            
    def get_object_data(self, obj_id: str) -> Optional[Dict[str, Any]]:
        """
        获取对象数据
        
        Args:
            obj_id: 对象ID
            
        Returns:
            对象数据或None
        """
        return self.sync_objects.get(obj_id)
        
    def get_sync_objects(self) -> Dict[str, Any]:
        """
        获取所有同步对象
        
        Returns:
            同步对象字典
        """
        return self.sync_objects.copy()
        
    def get_local_objects(self) -> Dict[str, Any]:
        """
        获取所有本地对象
        
        Returns:
            本地对象字典
        """
        return self.local_objects.copy()
        
    def get_remote_objects(self) -> Dict[str, Any]:
        """
        获取所有远程对象
        
        Returns:
            远程对象字典
        """
        return self.remote_objects.copy()
        
    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 get_sync_stats(self) -> Dict[str, Any]:
        """
        获取同步统计信息
        
        Returns:
            统计信息字典
        """
        return self.sync_stats.copy()
        
    def reset_sync_stats(self):
        """重置同步统计信息"""
        try:
            self.sync_stats = {
                'objects_synced': 0,
                'sync_operations': 0,
                'interpolations': 0,
                'extrapolations': 0,
                'sync_errors': 0,
                'delta_compressions': 0
            }
            print("✓ 同步统计信息已重置")
        except Exception as e:
            print(f"✗ 同步统计信息重置失败: {e}")
            
    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}")