"""
事件系统模块
负责处理和分发各种输入事件
"""

import time
from typing import Dict, Any, List, Optional, Callable
import threading
import queue
from enum import Enum
from dataclasses import dataclass
from collections import defaultdict

class EventType(Enum):
    """事件类型枚举"""
    INPUT_PRESSED = "input_pressed"
    INPUT_RELEASED = "input_released"
    INPUT_HELD = "input_held"
    INPUT_CLICKED = "input_clicked"
    INPUT_DOUBLE_CLICKED = "input_double_clicked"
    INPUT_LONG_PRESSED = "input_long_pressed"
    INPUT_LONG_PRESSING = "input_long_pressing"
    INPUT_SWIPE = "input_swipe"
    INPUT_DRAG = "input_drag"
    INPUT_PINCH = "input_pinch"
    INPUT_ROTATE = "input_rotate"
    INPUT_SHAKE = "input_shake"
    DEVICE_CONNECTED = "device_connected"
    DEVICE_DISCONNECTED = "device_disconnected"
    GESTURE_RECOGNIZED = "gesture_recognized"
    HAPTIC_FEEDBACK = "haptic_feedback"
    CUSTOM = "custom"

@dataclass
class InputEvent:
    """输入事件数据类"""
    event_type: EventType
    device_id: int
    input_id: str
    value: Any = None
    timestamp: float = 0.0
    position: tuple = None  # (x, y) 对于触摸和鼠标事件
    velocity: tuple = None  # (vx, vy) 对于移动事件
    duration: float = 0.0   # 事件持续时间
    metadata: Dict[str, Any] = None

class EventSystem:
    """
    事件系统
    负责处理和分发各种输入事件
    """
    
    def __init__(self, plugin):
        """
        初始化事件系统
        
        Args:
            plugin: 多平台输入支持插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 事件队列
        self.event_queue = queue.Queue()
        self.processed_events = queue.Queue()
        
        # 事件监听器
        self.event_listeners = defaultdict(list)
        
        # 事件过滤器
        self.event_filters = []
        
        # 事件配置
        self.event_config = {
            'queue_max_size': 1000,
            'process_interval': 0.016,  # ~60 FPS
            'batch_process_size': 10,
            'enable_event_coalescing': True,
            'enable_event_filtering': True,
            'duplicate_suppression_time': 0.01  # 10ms内重复事件抑制
        }
        
        # 事件历史记录
        self.event_history = []
        self.history_config = {
            'max_history_size': 100,
            'record_all_events': False,
            'recorded_event_types': [
                EventType.INPUT_PRESSED,
                EventType.INPUT_RELEASED,
                EventType.GESTURE_RECOGNIZED
            ]
        }
        
        # 事件统计
        self.event_stats = {
            'events_queued': 0,
            'events_processed': 0,
            'events_dropped': 0,
            'listeners_called': 0,
            'filters_applied': 0,
            'events_coalesced': 0
        }
        
        # 时间戳记录（用于重复事件抑制）
        self.last_event_timestamps = {}
        
        # 线程管理
        self.event_thread = None
        self.running = False
        
        # 锁
        self.event_lock = threading.Lock()
        self.history_lock = threading.Lock()
        
        # 回调函数
        self.global_event_callback = None
        
        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.event_thread = threading.Thread(target=self._event_processing_loop, daemon=True)
            self.event_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.event_thread and self.event_thread.is_alive():
                self.event_thread.join(timeout=2.0)
                
            # 清理队列
            while not self.event_queue.empty():
                try:
                    self.event_queue.get_nowait()
                except queue.Empty:
                    break
                    
            while not self.processed_events.empty():
                try:
                    self.processed_events.get_nowait()
                except queue.Empty:
                    break
                    
            print("✓ 事件系统已禁用")
            
        except Exception as e:
            print(f"✗ 事件系统禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理事件系统资源"""
        try:
            self.disable()
            self.event_listeners.clear()
            self.event_filters.clear()
            self.event_history.clear()
            self.last_event_timestamps.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_completed_events()
            
            # 更新统计信息
            pass  # 统计信息在其他地方更新
            
        except Exception as e:
            print(f"✗ 事件系统更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _event_processing_loop(self):
        """事件处理循环"""
        try:
            process_interval = self.event_config['process_interval']
            
            while self.running:
                if self.enabled:
                    self._process_events()
                    
                time.sleep(process_interval)
                
        except Exception as e:
            print(f"✗ 事件处理循环失败: {e}")
            
    def _process_events(self):
        """处理事件队列"""
        try:
            processed_count = 0
            batch_size = self.event_config['batch_process_size']
            
            while processed_count < batch_size and not self.event_queue.empty():
                try:
                    event = self.event_queue.get_nowait()
                    
                    # 应用事件过滤器
                    if self.event_config['enable_event_filtering']:
                        if not self._apply_filters(event):
                            self.event_stats['events_dropped'] += 1
                            continue
                            
                    # 事件合并
                    if self.event_config['enable_event_coalescing']:
                        if self._coalesce_event(event):
                            self.event_stats['events_coalesced'] += 1
                            continue
                            
                    # 重复事件抑制
                    if self._suppress_duplicate_event(event):
                        self.event_stats['events_dropped'] += 1
                        continue
                        
                    # 分发事件
                    self._dispatch_event(event)
                    
                    # 记录事件历史
                    self._record_event_history(event)
                    
                    self.event_stats['events_processed'] += 1
                    processed_count += 1
                    
                except queue.Empty:
                    break
                except Exception as e:
                    print(f"✗ 事件处理失败: {e}")
                    self.event_stats['events_dropped'] += 1
                    
        except Exception as e:
            print(f"✗ 事件队列处理失败: {e}")
            
    def _process_completed_events(self):
        """处理已完成的事件"""
        try:
            # 这里可以处理需要在主线程执行的事件
            pass
        except Exception as e:
            print(f"✗ 已完成事件处理失败: {e}")
            
    def _apply_filters(self, event: InputEvent) -> bool:
        """
        应用事件过滤器
        
        Args:
            event: 输入事件
            
        Returns:
            是否通过过滤器
        """
        try:
            self.event_stats['filters_applied'] += len(self.event_filters)
            
            for filter_func in self.event_filters:
                if not filter_func(event):
                    return False
            return True
        except Exception as e:
            print(f"✗ 事件过滤器应用失败: {e}")
            return True  # 默认通过
            
    def _coalesce_event(self, event: InputEvent) -> bool:
        """
        合并事件（减少重复事件）
        
        Args:
            event: 输入事件
            
        Returns:
            是否合并了事件
        """
        try:
            # 简化的事件合并逻辑
            # 在实际实现中，可以基于事件类型和设备进行更复杂的合并
            return False
        except Exception as e:
            print(f"✗ 事件合并失败: {e}")
            return False
            
    def _suppress_duplicate_event(self, event: InputEvent) -> bool:
        """
        抑制重复事件
        
        Args:
            event: 输入事件
            
        Returns:
            是否抑制了事件
        """
        try:
            # 创建事件标识符
            event_key = f"{event.event_type.value}:{event.device_id}:{event.input_id}"
            
            current_time = time.time()
            last_time = self.last_event_timestamps.get(event_key, 0.0)
            
            if current_time - last_time < self.event_config['duplicate_suppression_time']:
                return True
                
            self.last_event_timestamps[event_key] = current_time
            return False
        except Exception as e:
            print(f"✗ 重复事件抑制失败: {e}")
            return False
            
    def _dispatch_event(self, event: InputEvent):
        """
        分发事件
        
        Args:
            event: 输入事件
        """
        try:
            # 调用全局回调
            if self.global_event_callback:
                try:
                    self.global_event_callback(event)
                except Exception as e:
                    print(f"✗ 全局事件回调执行失败: {e}")
                    
            # 调用特定类型监听器
            listeners = self.event_listeners[event.event_type]
            for listener in listeners:
                try:
                    listener(event)
                    self.event_stats['listeners_called'] += 1
                except Exception as e:
                    print(f"✗ 事件监听器执行失败: {e}")
                    
            # 将事件放入已完成队列（如果需要主线程处理）
            self.processed_events.put(event)
            
        except Exception as e:
            print(f"✗ 事件分发失败: {e}")
            
    def _record_event_history(self, event: InputEvent):
        """
        记录事件历史
        
        Args:
            event: 输入事件
        """
        try:
            # 检查是否需要记录此事件类型
            should_record = self.history_config['record_all_events'] or \
                           event.event_type in self.history_config['recorded_event_types']
                           
            if not should_record:
                return
                
            with self.history_lock:
                self.event_history.append(event)
                
                # 保持历史记录大小
                if len(self.event_history) > self.history_config['max_history_size']:
                    self.event_history.pop(0)
                    
        except Exception as e:
            print(f"✗ 事件历史记录失败: {e}")
            
    def queue_event(self, event: InputEvent):
        """
        将事件加入队列
        
        Args:
            event: 输入事件
        """
        try:
            if not self.enabled:
                return
                
            # 设置时间戳
            if event.timestamp == 0.0:
                event.timestamp = time.time()
                
            # 检查队列大小
            if self.event_queue.qsize() >= self.event_config['queue_max_size']:
                # 丢弃最旧的事件
                try:
                    self.event_queue.get_nowait()
                    self.event_stats['events_dropped'] += 1
                except queue.Empty:
                    pass
                    
            self.event_queue.put(event)
            self.event_stats['events_queued'] += 1
            
        except Exception as e:
            print(f"✗ 事件入队失败: {e}")
            
    def create_event(self, event_type: EventType, device_id: int, input_id: str,
                    value: Any = None, position: tuple = None, velocity: tuple = None,
                    duration: float = 0.0, metadata: Dict[str, Any] = None) -> InputEvent:
        """
        创建输入事件
        
        Args:
            event_type: 事件类型
            device_id: 设备ID
            input_id: 输入ID
            value: 输入值
            position: 位置坐标
            velocity: 速度向量
            duration: 持续时间
            metadata: 元数据
            
        Returns:
            输入事件
        """
        try:
            event = InputEvent(
                event_type=event_type,
                device_id=device_id,
                input_id=input_id,
                value=value,
                timestamp=time.time(),
                position=position,
                velocity=velocity,
                duration=duration,
                metadata=metadata or {}
            )
            return event
        except Exception as e:
            print(f"✗ 事件创建失败: {e}")
            return None
            
    def register_event_listener(self, event_type: EventType, listener: Callable):
        """
        注册事件监听器
        
        Args:
            event_type: 事件类型
            listener: 监听器回调函数
        """
        try:
            self.event_listeners[event_type].append(listener)
            print(f"✓ 事件监听器已注册: {event_type.value}")
        except Exception as e:
            print(f"✗ 事件监听器注册失败: {e}")
            
    def unregister_event_listener(self, event_type: EventType, listener: Callable):
        """
        注销事件监听器
        
        Args:
            event_type: 事件类型
            listener: 监听器回调函数
        """
        try:
            if event_type in self.event_listeners:
                if listener in self.event_listeners[event_type]:
                    self.event_listeners[event_type].remove(listener)
                    print(f"✓ 事件监听器已注销: {event_type.value}")
        except Exception as e:
            print(f"✗ 事件监听器注销失败: {e}")
            
    def add_event_filter(self, filter_func: Callable[[InputEvent], bool]):
        """
        添加事件过滤器
        
        Args:
            filter_func: 过滤器函数，返回True表示通过，False表示过滤
        """
        try:
            self.event_filters.append(filter_func)
            print("✓ 事件过滤器已添加")
        except Exception as e:
            print(f"✗ 事件过滤器添加失败: {e}")
            
    def remove_event_filter(self, filter_func: Callable[[InputEvent], bool]):
        """
        移除事件过滤器
        
        Args:
            filter_func: 过滤器函数
        """
        try:
            if filter_func in self.event_filters:
                self.event_filters.remove(filter_func)
                print("✓ 事件过滤器已移除")
        except Exception as e:
            print(f"✗ 事件过滤器移除失败: {e}")
            
    def set_global_event_callback(self, callback: Callable[[InputEvent], None]):
        """
        设置全局事件回调
        
        Args:
            callback: 全局回调函数
        """
        try:
            self.global_event_callback = callback
            print("✓ 全局事件回调已设置")
        except Exception as e:
            print(f"✗ 全局事件回调设置失败: {e}")
            
    def get_event_history(self, event_type: EventType = None, limit: int = None) -> List[InputEvent]:
        """
        获取事件历史记录
        
        Args:
            event_type: 事件类型过滤器
            limit: 返回事件数量限制
            
        Returns:
            事件历史列表
        """
        try:
            with self.history_lock:
                history = self.event_history.copy()
                
            if event_type:
                history = [event for event in history if event.event_type == event_type]
                
            if limit:
                history = history[-limit:]
                
            return history
        except Exception as e:
            print(f"✗ 事件历史获取失败: {e}")
            return []
            
    def clear_event_history(self):
        """清空事件历史"""
        try:
            with self.history_lock:
                self.event_history.clear()
            print("✓ 事件历史已清空")
        except Exception as e:
            print(f"✗ 事件历史清空失败: {e}")
            
    def set_event_config(self, config: Dict[str, Any]):
        """
        设置事件配置
        
        Args:
            config: 事件配置字典
        """
        try:
            self.event_config.update(config)
            print(f"✓ 事件配置已更新: {self.event_config}")
        except Exception as e:
            print(f"✗ 事件配置设置失败: {e}")
            
    def get_event_config(self) -> Dict[str, Any]:
        """
        获取事件配置
        
        Returns:
            事件配置字典
        """
        return self.event_config.copy()
        
    def set_history_config(self, config: Dict[str, Any]):
        """
        设置历史记录配置
        
        Args:
            config: 历史记录配置字典
        """
        try:
            self.history_config.update(config)
            print(f"✓ 历史记录配置已更新: {self.history_config}")
        except Exception as e:
            print(f"✗ 历史记录配置设置失败: {e}")
            
    def get_history_config(self) -> Dict[str, Any]:
        """
        获取历史记录配置
        
        Returns:
            历史记录配置字典
        """
        return self.history_config.copy()
        
    def get_event_stats(self) -> Dict[str, int]:
        """
        获取事件统计信息
        
        Returns:
            事件统计字典
        """
        return self.event_stats.copy()
        
    def reset_event_stats(self):
        """重置事件统计信息"""
        try:
            self.event_stats = {
                'events_queued': 0,
                'events_processed': 0,
                'events_dropped': 0,
                'listeners_called': 0,
                'filters_applied': 0,
                'events_coalesced': 0
            }
            print("✓ 事件统计信息已重置")
        except Exception as e:
            print(f"✗ 事件统计信息重置失败: {e}")
            
    def get_pending_events_count(self) -> int:
        """
        获取待处理事件数量
        
        Returns:
            待处理事件数量
        """
        try:
            return self.event_queue.qsize()
        except Exception as e:
            print(f"✗ 待处理事件数量获取失败: {e}")
            return 0
            
    def flush_events(self):
        """清空事件队列"""
        try:
            while not self.event_queue.empty():
                try:
                    self.event_queue.get_nowait()
                except queue.Empty:
                    break
            print("✓ 事件队列已清空")
        except Exception as e:
            print(f"✗ 事件队列清空失败: {e}")