"""
输入管理器模块
负责管理所有输入设备和事件处理
"""

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

class InputType(Enum):
    """输入类型枚举"""
    KEYBOARD = "keyboard"
    MOUSE = "mouse"
    TOUCH = "touch"
    GAMEPAD = "gamepad"
    VR_CONTROLLER = "vr_controller"
    MOTION = "motion"
    CUSTOM = "custom"

class InputState(Enum):
    """输入状态枚举"""
    IDLE = "idle"
    PRESSED = "pressed"
    HELD = "held"
    RELEASED = "released"

class InputManager:
    """
    输入管理器
    负责管理所有输入设备、处理输入事件和维护输入状态
    """
    
    def __init__(self, plugin):
        """
        初始化输入管理器
        
        Args:
            plugin: 多平台输入支持插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 输入设备字典
        self.input_devices = {}
        self.device_counter = 0
        
        # 输入状态映射
        self.input_states = {}
        
        # 事件监听器
        self.event_listeners = {}
        
        # 输入配置
        self.input_config = {
            'polling_rate': 120,           # 轮询频率(Hz)
            'deadzone': 0.1,               # 死区阈值
            'double_click_time': 0.3,      # 双击时间阈值(秒)
            'long_press_time': 0.5,        # 长按时间阈值(秒)
            'swipe_threshold': 50,         # 滑动阈值(像素)
            'gesture_timeout': 1.0         # 手势超时时间(秒)
        }
        
        # 输入缓冲区
        self.input_buffer = []
        self.buffer_lock = threading.Lock()
        
        # 时间戳记录
        self.last_input_time = {}
        self.press_start_time = {}
        
        # 统计信息
        self.stats = {
            'total_inputs': 0,
            'active_devices': 0,
            'events_processed': 0,
            'buffer_size': 0
        }
        
        # 回调函数
        self.input_callbacks = {}
        self.action_callbacks = {}
        
        # 线程管理
        self.update_thread = None
        self.running = False
        
        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.update_thread = threading.Thread(target=self._update_loop, daemon=True)
            self.update_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.update_thread and self.update_thread.is_alive():
                self.update_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.input_devices.clear()
            self.input_states.clear()
            self.event_listeners.clear()
            self.input_buffer.clear()
            self.input_callbacks.clear()
            self.action_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
                
            # 处理输入缓冲区
            self._process_input_buffer()
            
            # 更新统计信息
            with self.buffer_lock:
                self.stats['buffer_size'] = len(self.input_buffer)
                
        except Exception as e:
            print(f"✗ 输入管理器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_loop(self):
        """更新循环线程"""
        try:
            polling_interval = 1.0 / self.input_config['polling_rate']
            
            while self.running:
                if self.enabled:
                    # 检查长按事件
                    self._check_long_press_events()
                    
                    # 检查手势超时
                    self._check_gesture_timeouts()
                    
                time.sleep(polling_interval)
                
        except Exception as e:
            print(f"✗ 输入管理器更新循环失败: {e}")
            
    def _process_input_buffer(self):
        """处理输入缓冲区"""
        try:
            with self.buffer_lock:
                events_to_process = self.input_buffer[:]
                self.input_buffer.clear()
                
            for event in events_to_process:
                self._handle_input_event(event)
                
        except Exception as e:
            print(f"✗ 输入缓冲区处理失败: {e}")
            
    def _handle_input_event(self, event: Dict[str, Any]):
        """
        处理输入事件
        
        Args:
            event: 输入事件字典
        """
        try:
            event_type = event.get('type')
            device_id = event.get('device_id')
            input_id = event.get('input_id')
            value = event.get('value')
            timestamp = event.get('timestamp', time.time())
            
            # 更新输入状态
            state_key = f"{device_id}:{input_id}"
            old_value = self.input_states.get(state_key, 0.0)
            self.input_states[state_key] = value
            
            # 更新时间戳
            self.last_input_time[state_key] = timestamp
            
            # 确定输入状态变化
            if abs(value) > self.input_config['deadzone']:
                if abs(old_value) <= self.input_config['deadzone']:
                    # 按下事件
                    self.press_start_time[state_key] = timestamp
                    self._trigger_event('input_pressed', {
                        'device_id': device_id,
                        'input_id': input_id,
                        'value': value,
                        'timestamp': timestamp
                    })
                else:
                    # 持续按住事件
                    self._trigger_event('input_held', {
                        'device_id': device_id,
                        'input_id': input_id,
                        'value': value,
                        'timestamp': timestamp
                    })
            else:
                if abs(old_value) > self.input_config['deadzone']:
                    # 释放事件
                    press_duration = timestamp - self.press_start_time.get(state_key, timestamp)
                    self._trigger_event('input_released', {
                        'device_id': device_id,
                        'input_id': input_id,
                        'value': value,
                        'duration': press_duration,
                        'timestamp': timestamp
                    })
                    
                    # 检查是否为点击事件
                    if press_duration < self.input_config['long_press_time']:
                        self._trigger_event('input_clicked', {
                            'device_id': device_id,
                            'input_id': input_id,
                            'timestamp': timestamp
                        })
                        
                        # 检查是否为双击事件
                        last_click_time = self.last_input_time.get(f"click:{state_key}", 0)
                        if timestamp - last_click_time < self.input_config['double_click_time']:
                            self._trigger_event('input_double_clicked', {
                                'device_id': device_id,
                                'input_id': input_id,
                                'timestamp': timestamp
                            })
                        self.last_input_time[f"click:{state_key}"] = timestamp
                        
                    # 检查是否为长按事件
                    elif press_duration >= self.input_config['long_press_time']:
                        self._trigger_event('input_long_pressed', {
                            'device_id': device_id,
                            'input_id': input_id,
                            'duration': press_duration,
                            'timestamp': timestamp
                        })
                        
            # 更新统计信息
            self.stats['events_processed'] += 1
            
        except Exception as e:
            print(f"✗ 输入事件处理失败: {e}")
            
    def _check_long_press_events(self):
        """检查长按事件"""
        try:
            current_time = time.time()
            for state_key, start_time in self.press_start_time.items():
                if state_key in self.input_states:
                    value = self.input_states[state_key]
                    if abs(value) > self.input_config['deadzone']:
                        duration = current_time - start_time
                        if duration >= self.input_config['long_press_time']:
                            # 检查是否已经触发过长按事件
                            last_long_press = self.last_input_time.get(f"long_press:{state_key}", 0)
                            if current_time - last_long_press > self.input_config['long_press_time']:
                                device_id, input_id = state_key.split(':', 1)
                                self._trigger_event('input_long_pressing', {
                                    'device_id': device_id,
                                    'input_id': input_id,
                                    'value': value,
                                    'duration': duration,
                                    'timestamp': current_time
                                })
                                self.last_input_time[f"long_press:{state_key}"] = current_time
                                
        except Exception as e:
            print(f"✗ 长按事件检查失败: {e}")
            
    def _check_gesture_timeouts(self):
        """检查手势超时"""
        try:
            # 这里可以实现手势超时检查逻辑
            pass
        except Exception as e:
            print(f"✗ 手势超时检查失败: {e}")
            
    def add_input_device(self, device_type: InputType, 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,
                'last_seen': time.time(),
                'input_states': {}
            }
            
            self.input_devices[device_id] = device_info
            self.stats['active_devices'] += 1
            
            print(f"✓ 输入设备已添加: {device_name} (ID: {device_id})")
            return device_id
            
        except Exception as e:
            print(f"✗ 输入设备添加失败: {e}")
            return -1
            
    def remove_input_device(self, device_id: int) -> bool:
        """
        移除输入设备
        
        Args:
            device_id: 设备ID
            
        Returns:
            是否移除成功
        """
        try:
            if device_id in self.input_devices:
                device_name = self.input_devices[device_id]['name']
                del self.input_devices[device_id]
                self.stats['active_devices'] -= 1
                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 get_input_device(self, device_id: int) -> Optional[Dict[str, Any]]:
        """
        获取输入设备信息
        
        Args:
            device_id: 设备ID
            
        Returns:
            设备信息字典或None
        """
        return self.input_devices.get(device_id)
        
    def get_all_input_devices(self) -> Dict[int, Dict[str, Any]]:
        """
        获取所有输入设备
        
        Returns:
            所有设备信息字典
        """
        return self.input_devices.copy()
        
    def submit_input_event(self, event: Dict[str, Any]):
        """
        提交输入事件到缓冲区
        
        Args:
            event: 输入事件字典
        """
        try:
            with self.buffer_lock:
                self.input_buffer.append(event)
                self.stats['total_inputs'] += 1
        except Exception as e:
            print(f"✗ 输入事件提交失败: {e}")
            
    def register_event_listener(self, event_type: str, callback: Callable):
        """
        注册事件监听器
        
        Args:
            event_type: 事件类型
            callback: 回调函数
        """
        try:
            if event_type not in self.event_listeners:
                self.event_listeners[event_type] = []
            self.event_listeners[event_type].append(callback)
            print(f"✓ 事件监听器已注册: {event_type}")
        except Exception as e:
            print(f"✗ 事件监听器注册失败: {e}")
            
    def unregister_event_listener(self, event_type: str, callback: Callable):
        """
        注销事件监听器
        
        Args:
            event_type: 事件类型
            callback: 回调函数
        """
        try:
            if event_type in self.event_listeners:
                if callback in self.event_listeners[event_type]:
                    self.event_listeners[event_type].remove(callback)
                    print(f"✓ 事件监听器已注销: {event_type}")
        except Exception as e:
            print(f"✗ 事件监听器注销失败: {e}")
            
    def _trigger_event(self, event_type: str, event_data: Dict[str, Any]):
        """
        触发事件
        
        Args:
            event_type: 事件类型
            event_data: 事件数据
        """
        try:
            if event_type in self.event_listeners:
                for callback in self.event_listeners[event_type]:
                    try:
                        callback(event_data)
                    except Exception as e:
                        print(f"✗ 事件回调执行失败: {e}")
        except Exception as e:
            print(f"✗ 事件触发失败: {e}")
            
    def get_input_state(self, device_id: int, input_id: str) -> float:
        """
        获取输入状态
        
        Args:
            device_id: 设备ID
            input_id: 输入ID
            
        Returns:
            输入值
        """
        state_key = f"{device_id}:{input_id}"
        return self.input_states.get(state_key, 0.0)
        
    def is_input_pressed(self, device_id: int, input_id: str) -> bool:
        """
        检查输入是否被按下
        
        Args:
            device_id: 设备ID
            input_id: 输入ID
            
        Returns:
            是否被按下
        """
        value = self.get_input_state(device_id, input_id)
        return abs(value) > self.input_config['deadzone']
        
    def get_input_config(self) -> Dict[str, Any]:
        """
        获取输入配置
        
        Returns:
            输入配置字典
        """
        return self.input_config.copy()
        
    def set_input_config(self, config: Dict[str, Any]):
        """
        设置输入配置
        
        Args:
            config: 输入配置字典
        """
        try:
            self.input_config.update(config)
            print(f"✓ 输入配置已更新: {self.input_config}")
        except Exception as e:
            print(f"✗ 输入配置设置失败: {e}")
            
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        try:
            self.stats = {
                'total_inputs': 0,
                'active_devices': 0,
                'events_processed': 0,
                'buffer_size': 0
            }
            print("✓ 输入管理器统计信息已重置")
        except Exception as e:
            print(f"✗ 输入管理器统计信息重置失败: {e}")
            
    def register_action_callback(self, action_name: str, callback: Callable):
        """
        注册动作回调
        
        Args:
            action_name: 动作名称
            callback: 回调函数
        """
        try:
            self.action_callbacks[action_name] = callback
            print(f"✓ 动作回调已注册: {action_name}")
        except Exception as e:
            print(f"✗ 动作回调注册失败: {e}")
            
    def trigger_action(self, action_name: str, action_data: Dict[str, Any] = None):
        """
        触发动作
        
        Args:
            action_name: 动作名称
            action_data: 动作数据
        """
        try:
            if action_name in self.action_callbacks:
                callback = self.action_callbacks[action_name]
                try:
                    if action_data:
                        callback(action_data)
                    else:
                        callback()
                except Exception as e:
                    print(f"✗ 动作回调执行失败: {e}")
            else:
                print(f"✗ 未找到动作回调: {action_name}")
        except Exception as e:
            print(f"✗ 动作触发失败: {e}")