"""
触觉反馈管理器模块
负责管理和播放各种触觉反馈效果
"""

import time
from typing import Dict, Any, List, Optional, Callable, Union
from enum import Enum
import threading
import math

class HapticEffectType(Enum):
    """触觉效果类型枚举"""
    SIMPLE = "simple"
    PATTERN = "pattern"
    CURVE = "curve"
    CUSTOM = "custom"

class HapticDeviceType(Enum):
    """触觉设备类型枚举"""
    GAMEPAD = "gamepad"
    VR_CONTROLLER = "vr_controller"
    TOUCH_DEVICE = "touch_device"
    CUSTOM = "custom"

class HapticManager:
    """
    触觉反馈管理器
    负责管理和播放各种触觉反馈效果
    """
    
    def __init__(self, plugin):
        """
        初始化触觉反馈管理器
        
        Args:
            plugin: 多平台输入支持插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 触觉效果配置
        self.haptic_config = {
            'default_intensity': 0.5,      # 默认强度 (0.0-1.0)
            'default_duration': 0.2,       # 默认持续时间(秒)
            'max_intensity': 1.0,          # 最大强度
            'min_duration': 0.01,          # 最小持续时间(秒)
            'max_duration': 5.0,           # 最大持续时间(秒)
            'update_rate': 60.0,           # 更新频率(Hz)
            'enable_fading': True,         # 启用淡入淡出
            'fade_duration': 0.05          # 淡入淡出持续时间(秒)
        }
        
        # 触觉效果定义
        self.haptic_effects = {}
        self.effect_counter = 0
        
        # 活动效果
        self.active_effects = {}
        self.effect_instance_counter = 0
        
        # 设备支持
        self.supported_devices = {}
        self.device_counter = 0
        
        # 回调函数
        self.haptic_callbacks = {
            'effect_started': [],
            'effect_updated': [],
            'effect_finished': [],
            'effect_cancelled': []
        }
        
        # 统计信息
        self.haptic_stats = {
            'effects_registered': 0,
            'effects_played': 0,
            'effects_cancelled': 0,
            'active_effects': 0,
            'total_haptic_time': 0.0
        }
        
        # 时间戳记录
        self.last_effect_time = {}
        
        # 线程管理
        self.haptic_thread = None
        self.running = False
        self.haptic_lock = threading.Lock()
        
        print("✓ 触觉反馈管理器已创建")
        
    def initialize(self) -> bool:
        """
        初始化触觉反馈管理器
        
        Returns:
            是否初始化成功
        """
        try:
            # 创建默认触觉效果
            self._create_default_effects()
            
            # 初始化支持的设备
            self._initialize_supported_devices()
            
            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.haptic_thread = threading.Thread(target=self._haptic_update_loop, daemon=True)
            self.haptic_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.haptic_thread and self.haptic_thread.is_alive():
                self.haptic_thread.join(timeout=2.0)
                
            # 停止所有活动效果
            self.stop_all_effects()
            
            print("✓ 触觉反馈管理器已禁用")
            
        except Exception as e:
            print(f"✗ 触觉反馈管理器禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理触觉反馈管理器资源"""
        try:
            self.disable()
            self.haptic_effects.clear()
            self.active_effects.clear()
            self.supported_devices.clear()
            self.haptic_callbacks.clear()
            self.last_effect_time.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
                
            # 更新统计信息
            self.haptic_stats['active_effects'] = len(self.active_effects)
            
        except Exception as e:
            print(f"✗ 触觉反馈管理器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _haptic_update_loop(self):
        """触觉更新循环"""
        try:
            update_interval = 1.0 / self.haptic_config['update_rate']
            
            while self.running:
                if self.enabled:
                    self._update_active_effects()
                    
                time.sleep(update_interval)
                
        except Exception as e:
            print(f"✗ 触觉更新循环失败: {e}")
            
    def _update_active_effects(self):
        """更新活动效果"""
        try:
            current_time = time.time()
            finished_effects = []
            
            with self.haptic_lock:
                for effect_id, effect_data in self.active_effects.items():
                    start_time = effect_data['start_time']
                    duration = effect_data['duration']
                    elapsed_time = current_time - start_time
                    
                    # 检查效果是否完成
                    if elapsed_time >= duration:
                        finished_effects.append(effect_id)
                        continue
                        
                    # 更新效果强度
                    intensity = self._calculate_effect_intensity(effect_data, elapsed_time)
                    effect_data['current_intensity'] = intensity
                    
                    # 应用效果到设备
                    self._apply_haptic_effect(effect_data['device_id'], intensity)
                    
                    # 触发更新回调
                    self._trigger_haptic_callback('effect_updated', {
                        'effect_id': effect_id,
                        'device_id': effect_data['device_id'],
                        'intensity': intensity,
                        'elapsed_time': elapsed_time
                    })
                    
            # 处理完成的效果
            for effect_id in finished_effects:
                self._finish_effect(effect_id)
                
        except Exception as e:
            print(f"✗ 活动效果更新失败: {e}")
            
    def _calculate_effect_intensity(self, effect_data: Dict[str, Any], elapsed_time: float) -> float:
        """
        计算效果强度
        
        Args:
            effect_data: 效果数据
            elapsed_time: 已经过的时间
            
        Returns:
            效果强度
        """
        try:
            duration = effect_data['duration']
            base_intensity = effect_data['intensity']
            
            # 检查是否启用淡入淡出
            if self.haptic_config['enable_fading']:
                fade_duration = self.haptic_config['fade_duration']
                
                # 淡入阶段
                if elapsed_time < fade_duration:
                    fade_ratio = elapsed_time / fade_duration
                    return base_intensity * fade_ratio
                    
                # 淡出阶段
                elif elapsed_time > duration - fade_duration:
                    fade_ratio = (duration - elapsed_time) / fade_duration
                    return base_intensity * fade_ratio
                    
            # 正常播放阶段
            return base_intensity
            
        except Exception as e:
            print(f"✗ 效果强度计算失败: {e}")
            return 0.0
            
    def _apply_haptic_effect(self, device_id: int, intensity: float):
        """
        应用触觉效果到设备
        
        Args:
            device_id: 设备ID
            intensity: 强度
        """
        try:
            # 这里应该实现实际的设备控制逻辑
            # 在实际实现中，会根据设备类型调用相应的API
            pass
        except Exception as e:
            print(f"✗ 触觉效果应用失败: {e}")
            
    def _finish_effect(self, effect_id: int):
        """
        完成效果
        
        Args:
            effect_id: 效果ID
        """
        try:
            with self.haptic_lock:
                if effect_id in self.active_effects:
                    effect_data = self.active_effects[effect_id]
                    
                    # 停止设备上的效果
                    self._stop_device_effect(effect_data['device_id'])
                    
                    # 更新统计信息
                    self.haptic_stats['effects_played'] += 1
                    self.haptic_stats['total_haptic_time'] += effect_data['duration']
                    
                    # 触发完成回调
                    self._trigger_haptic_callback('effect_finished', {
                        'effect_id': effect_id,
                        'device_id': effect_data['device_id'],
                        'duration': effect_data['duration']
                    })
                    
                    # 移除活动效果
                    del self.active_effects[effect_id]
                    
        except Exception as e:
            print(f"✗ 效果完成处理失败: {e}")
            
    def _stop_device_effect(self, device_id: int):
        """
        停止设备上的效果
        
        Args:
            device_id: 设备ID
        """
        try:
            # 这里应该实现实际的设备停止逻辑
            pass
        except Exception as e:
            print(f"✗ 设备效果停止失败: {e}")
            
    def _create_default_effects(self):
        """创建默认触觉效果"""
        try:
            # 简单点击效果
            self.create_haptic_effect(
                name="click",
                effect_type=HapticEffectType.SIMPLE,
                parameters={
                    'intensity': 0.6,
                    'duration': 0.1,
                    'attack_time': 0.02,
                    'decay_time': 0.02
                }
            )
            
            # 重击效果
            self.create_haptic_effect(
                name="heavy_click",
                effect_type=HapticEffectType.SIMPLE,
                parameters={
                    'intensity': 0.9,
                    'duration': 0.2,
                    'attack_time': 0.05,
                    'decay_time': 0.05
                }
            )
            
            # 软击效果
            self.create_haptic_effect(
                name="soft_click",
                effect_type=HapticEffectType.SIMPLE,
                parameters={
                    'intensity': 0.3,
                    'duration': 0.05,
                    'attack_time': 0.01,
                    'decay_time': 0.01
                }
            )
            
            # 震动效果
            self.create_haptic_effect(
                name="vibration",
                effect_type=HapticEffectType.PATTERN,
                parameters={
                    'pattern': [0.5, 0.2, 0.5, 0.2],  # 强度, 持续时间, 强度, 持续时间
                    'loop': True
                }
            )
            
            # 脉冲效果
            self.create_haptic_effect(
                name="pulse",
                effect_type=HapticEffectType.CURVE,
                parameters={
                    'curve': 'sine',  # sine, square, triangle, sawtooth
                    'frequency': 50.0,  # Hz
                    'amplitude': 0.7,
                    'duration': 1.0
                }
            )
            
            print("✓ 默认触觉效果创建完成")
            
        except Exception as e:
            print(f"✗ 默认触觉效果创建失败: {e}")
            
    def _initialize_supported_devices(self):
        """初始化支持的设备"""
        try:
            # 在实际实现中，这里会检测和初始化连接的设备
            print("✓ 支持的设备初始化完成")
        except Exception as e:
            print(f"✗ 支持的设备初始化失败: {e}")
            
    def create_haptic_effect(self, name: str, effect_type: HapticEffectType,
                           parameters: Dict[str, Any]) -> int:
        """
        创建触觉效果
        
        Args:
            name: 效果名称
            effect_type: 效果类型
            parameters: 参数字典
            
        Returns:
            效果ID
        """
        try:
            effect_id = self.effect_counter
            self.effect_counter += 1
            
            effect = {
                'id': effect_id,
                'name': name,
                'type': effect_type,
                'parameters': parameters,
                'created_time': time.time()
            }
            
            self.haptic_effects[effect_id] = effect
            self.haptic_stats['effects_registered'] += 1
            
            print(f"✓ 触觉效果已创建: {name} (ID: {effect_id})")
            return effect_id
            
        except Exception as e:
            print(f"✗ 触觉效果创建失败: {e}")
            return -1
            
    def remove_haptic_effect(self, effect_id: int) -> bool:
        """
        移除触觉效果
        
        Args:
            effect_id: 效果ID
            
        Returns:
            是否移除成功
        """
        try:
            if effect_id in self.haptic_effects:
                effect_name = self.haptic_effects[effect_id]['name']
                
                # 停止所有使用此效果的活动实例
                self._stop_effect_instances(effect_id)
                
                del self.haptic_effects[effect_id]
                print(f"✓ 触觉效果已移除: {effect_name} (ID: {effect_id})")
                return True
            else:
                print(f"✗ 触觉效果不存在: ID {effect_id}")
                return False
                
        except Exception as e:
            print(f"✗ 触觉效果移除失败: {e}")
            return False
            
    def _stop_effect_instances(self, effect_id: int):
        """
        停止效果的所有实例
        
        Args:
            effect_id: 效果ID
        """
        try:
            with self.haptic_lock:
                instances_to_stop = [
                    instance_id for instance_id, instance_data in self.active_effects.items()
                    if instance_data['effect_id'] == effect_id
                ]
                
            for instance_id in instances_to_stop:
                self.stop_haptic_effect(instance_id)
                
        except Exception as e:
            print(f"✗ 效果实例停止失败: {e}")
            
    def play_haptic_effect(self, effect_id: int, device_id: int,
                          intensity: float = None, duration: float = None) -> int:
        """
        播放触觉效果
        
        Args:
            effect_id: 效果ID
            device_id: 设备ID
            intensity: 强度(可选，覆盖效果默认值)
            duration: 持续时间(可选，覆盖效果默认值)
            
        Returns:
            效果实例ID
        """
        try:
            if not self.enabled:
                return -1
                
            if effect_id not in self.haptic_effects:
                print(f"✗ 触觉效果不存在: ID {effect_id}")
                return -1
                
            # 获取效果定义
            effect = self.haptic_effects[effect_id]
            
            # 使用默认值或传入值
            final_intensity = intensity if intensity is not None else effect['parameters'].get('intensity', self.haptic_config['default_intensity'])
            final_duration = duration if duration is not None else effect['parameters'].get('duration', self.haptic_config['default_duration'])
            
            # 限制值范围
            final_intensity = max(0.0, min(self.haptic_config['max_intensity'], final_intensity))
            final_duration = max(self.haptic_config['min_duration'], min(self.haptic_config['max_duration'], final_duration))
            
            # 创建效果实例
            instance_id = self.effect_instance_counter
            self.effect_instance_counter += 1
            
            effect_instance = {
                'instance_id': instance_id,
                'effect_id': effect_id,
                'device_id': device_id,
                'intensity': final_intensity,
                'duration': final_duration,
                'start_time': time.time(),
                'current_intensity': 0.0
            }
            
            with self.haptic_lock:
                self.active_effects[instance_id] = effect_instance
                
            # 触发开始回调
            self._trigger_haptic_callback('effect_started', {
                'effect_id': instance_id,
                'device_id': device_id,
                'effect_name': effect['name'],
                'intensity': final_intensity,
                'duration': final_duration
            })
            
            print(f"✓ 触觉效果已播放: {effect['name']} (实例ID: {instance_id})")
            return instance_id
            
        except Exception as e:
            print(f"✗ 触觉效果播放失败: {e}")
            return -1
            
    def stop_haptic_effect(self, instance_id: int) -> bool:
        """
        停止触觉效果实例
        
        Args:
            instance_id: 效果实例ID
            
        Returns:
            是否停止成功
        """
        try:
            with self.haptic_lock:
                if instance_id in self.active_effects:
                    effect_data = self.active_effects[instance_id]
                    
                    # 停止设备上的效果
                    self._stop_device_effect(effect_data['device_id'])
                    
                    # 更新统计信息
                    self.haptic_stats['effects_cancelled'] += 1
                    
                    # 触发取消回调
                    self._trigger_haptic_callback('effect_cancelled', {
                        'effect_id': instance_id,
                        'device_id': effect_data['device_id']
                    })
                    
                    # 移除活动效果
                    del self.active_effects[instance_id]
                    
                    print(f"✓ 触觉效果已停止: 实例ID {instance_id}")
                    return True
                else:
                    print(f"✗ 触觉效果实例不存在: ID {instance_id}")
                    return False
                    
        except Exception as e:
            print(f"✗ 触觉效果停止失败: {e}")
            return False
            
    def stop_all_effects(self):
        """停止所有触觉效果"""
        try:
            with self.haptic_lock:
                active_instances = list(self.active_effects.keys())
                
            for instance_id in active_instances:
                self.stop_haptic_effect(instance_id)
                
            print("✓ 所有触觉效果已停止")
            
        except Exception as e:
            print(f"✗ 停止所有触觉效果失败: {e}")
            
    def play_simple_effect(self, device_id: int, intensity: float = None,
                          duration: float = None) -> int:
        """
        播放简单触觉效果
        
        Args:
            device_id: 设备ID
            intensity: 强度
            duration: 持续时间
            
        Returns:
            效果实例ID
        """
        try:
            # 创建临时简单效果
            temp_effect_id = self.create_haptic_effect(
                name=f"temp_simple_{int(time.time()*1000)}",
                effect_type=HapticEffectType.SIMPLE,
                parameters={
                    'intensity': intensity or self.haptic_config['default_intensity'],
                    'duration': duration or self.haptic_config['default_duration']
                }
            )
            
            # 播放效果
            instance_id = self.play_haptic_effect(temp_effect_id, device_id)
            
            # 移除临时效果定义
            if temp_effect_id >= 0:
                # 延迟移除，确保效果播放完成
                threading.Timer(
                    duration or self.haptic_config['default_duration'] + 0.1,
                    lambda: self.remove_haptic_effect(temp_effect_id)
                ).start()
                
            return instance_id
            
        except Exception as e:
            print(f"✗ 简单触觉效果播放失败: {e}")
            return -1
            
    def register_haptic_callback(self, callback_type: str, callback: Callable):
        """
        注册触觉回调
        
        Args:
            callback_type: 回调类型('effect_started', 'effect_updated', 'effect_finished', 'effect_cancelled')
            callback: 回调函数
        """
        try:
            if callback_type in self.haptic_callbacks:
                self.haptic_callbacks[callback_type].append(callback)
                print(f"✓ 触觉回调已注册: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 触觉回调注册失败: {e}")
            
    def unregister_haptic_callback(self, callback_type: str, callback: Callable):
        """
        注销触觉回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.haptic_callbacks:
                if callback in self.haptic_callbacks[callback_type]:
                    self.haptic_callbacks[callback_type].remove(callback)
                    print(f"✓ 触觉回调已注销: {callback_type}")
        except Exception as e:
            print(f"✗ 触觉回调注销失败: {e}")
            
    def _trigger_haptic_callback(self, callback_type: str, data: Dict[str, Any]):
        """
        触发触觉回调
        
        Args:
            callback_type: 回调类型
            data: 回调数据
        """
        try:
            if callback_type in self.haptic_callbacks:
                for callback in self.haptic_callbacks[callback_type]:
                    try:
                        callback(data)
                    except Exception as e:
                        print(f"✗ 触觉回调执行失败: {e}")
        except Exception as e:
            print(f"✗ 触觉回调触发失败: {e}")
            
    def add_supported_device(self, device_type: HapticDeviceType, device_name: str,
                           capabilities: List[str]) -> int:
        """
        添加支持的设备
        
        Args:
            device_type: 设备类型
            device_name: 设备名称
            capabilities: 设备功能列表
            
        Returns:
            设备ID
        """
        try:
            device_id = self.device_counter
            self.device_counter += 1
            
            device_info = {
                'id': device_id,
                'type': device_type,
                'name': device_name,
                'capabilities': capabilities,
                'connected': True,
                'max_intensity': 1.0,
                'supported_effects': []
            }
            
            self.supported_devices[device_id] = device_info
            
            print(f"✓ 支持的设备已添加: {device_name} (ID: {device_id})")
            return device_id
            
        except Exception as e:
            print(f"✗ 支持的设备添加失败: {e}")
            return -1
            
    def remove_supported_device(self, device_id: int) -> bool:
        """
        移除支持的设备
        
        Args:
            device_id: 设备ID
            
        Returns:
            是否移除成功
        """
        try:
            if device_id in self.supported_devices:
                device_name = self.supported_devices[device_id]['name']
                
                # 停止设备上的所有效果
                self._stop_device_effects(device_id)
                
                del self.supported_devices[device_id]
                print(f"✓ 支持的设备已移除: {device_name} (ID: {device_id})")
                return True
            else:
                print(f"✗ 支持的设备不存在: ID {device_id}")
                return False
                
        except Exception as e:
            print(f"✗ 支持的设备移除失败: {e}")
            return False
            
    def _stop_device_effects(self, device_id: int):
        """
        停止设备上的所有效果
        
        Args:
            device_id: 设备ID
        """
        try:
            with self.haptic_lock:
                effects_to_stop = [
                    instance_id for instance_id, instance_data in self.active_effects.items()
                    if instance_data['device_id'] == device_id
                ]
                
            for instance_id in effects_to_stop:
                self.stop_haptic_effect(instance_id)
                
        except Exception as e:
            print(f"✗ 设备效果停止失败: {e}")
            
    def get_haptic_effect(self, effect_id: int) -> Optional[Dict[str, Any]]:
        """
        获取触觉效果信息
        
        Args:
            effect_id: 效果ID
            
        Returns:
            效果信息字典或None
        """
        return self.haptic_effects.get(effect_id)
        
    def get_all_haptic_effects(self) -> Dict[int, Dict[str, Any]]:
        """
        获取所有触觉效果
        
        Returns:
            所有触觉效果字典
        """
        return self.haptic_effects.copy()
        
    def get_supported_devices(self) -> Dict[int, Dict[str, Any]]:
        """
        获取支持的设备
        
        Returns:
            支持的设备字典
        """
        return self.supported_devices.copy()
        
    def set_haptic_config(self, config: Dict[str, Any]):
        """
        设置触觉配置
        
        Args:
            config: 触觉配置字典
        """
        try:
            self.haptic_config.update(config)
            print(f"✓ 触觉配置已更新: {self.haptic_config}")
        except Exception as e:
            print(f"✗ 触觉配置设置失败: {e}")
            
    def get_haptic_config(self) -> Dict[str, Any]:
        """
        获取触觉配置
        
        Returns:
            触觉配置字典
        """
        return self.haptic_config.copy()
        
    def get_haptic_stats(self) -> Dict[str, Any]:
        """
        获取触觉统计信息
        
        Returns:
            触觉统计字典
        """
        return self.haptic_stats.copy()
        
    def reset_haptic_stats(self):
        """重置触觉统计信息"""
        try:
            self.haptic_stats = {
                'effects_registered': len(self.haptic_effects),
                'effects_played': 0,
                'effects_cancelled': 0,
                'active_effects': 0,
                'total_haptic_time': 0.0
            }
            print("✓ 触觉统计信息已重置")
        except Exception as e:
            print(f"✗ 触觉统计信息重置失败: {e}")
            
    def get_active_effects(self) -> Dict[int, Dict[str, Any]]:
        """
        获取活动效果
        
        Returns:
            活动效果字典
        """
        with self.haptic_lock:
            return self.active_effects.copy()