"""
工具类模块
提供各种实用工具函数和辅助类
"""

import time
import math
from typing import Dict, Any, List, Optional, Tuple, Union
from enum import Enum
import json
import hashlib

class InputUtils:
    """
    输入工具类
    提供各种实用工具函数和辅助类
    """
    
    def __init__(self, plugin):
        """
        初始化输入工具类
        
        Args:
            plugin: 多平台输入支持插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 工具配置
        self.utils_config = {
            'enable_logging': True,
            'log_level': 'INFO',
            'max_log_entries': 1000,
            'enable_performance_monitoring': True,
            'performance_sample_rate': 10.0,  # Hz
            'cache_size': 100,
            'enable_data_compression': False
        }
        
        # 日志系统
        self.log_entries = []
        self.log_counter = 0
        
        # 性能监控
        self.performance_metrics = {
            'update_times': [],
            'memory_usage': 0,
            'cpu_usage': 0,
            'frame_rate': 0.0,
            'last_sample_time': 0.0
        }
        
        # 缓存系统
        self.cache = {}
        self.cache_timestamps = {}
        
        # 数据转换配置
        self.conversion_config = {
            'angle_unit': 'radians',  # 'radians' or 'degrees'
            'distance_unit': 'pixels',  # 'pixels', 'meters', 'units'
            'time_unit': 'seconds'     # 'seconds', 'milliseconds'
        }
        
        # 统计信息
        self.utils_stats = {
            'functions_called': 0,
            'cache_hits': 0,
            'cache_misses': 0,
            'data_converted': 0,
            'logs_written': 0,
            'errors_handled': 0
        }
        
        # 时间戳记录
        self.last_performance_sample = 0.0
        self.startup_time = time.time()
        
        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.log_entries.clear()
            self.performance_metrics.clear()
            self.cache.clear()
            self.cache_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
                
            # 更新性能监控
            if self.utils_config['enable_performance_monitoring']:
                self._update_performance_metrics(dt)
                
        except Exception as e:
            print(f"✗ 输入工具类更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_performance_metrics(self, dt: float):
        """
        更新性能监控指标
        
        Args:
            dt: 时间增量
        """
        try:
            current_time = time.time()
            
            # 采样间隔控制
            if current_time - self.last_performance_sample >= 1.0 / self.utils_config['performance_sample_rate']:
                # 记录更新时间
                self.performance_metrics['update_times'].append(dt)
                
                # 保持采样数量
                if len(self.performance_metrics['update_times']) > 100:
                    self.performance_metrics['update_times'].pop(0)
                    
                # 计算帧率
                if dt > 0:
                    self.performance_metrics['frame_rate'] = 1.0 / dt
                    
                self.last_performance_sample = current_time
                
        except Exception as e:
            print(f"✗ 性能监控更新失败: {e}")
            
    # 日志工具函数
    def log_message(self, level: str, message: str, data: Any = None):
        """
        记录日志消息
        
        Args:
            level: 日志级别
            message: 日志消息
            data: 附加数据
        """
        try:
            if not self.utils_config['enable_logging']:
                return
                
            log_entry = {
                'id': self.log_counter,
                'timestamp': time.time(),
                'level': level,
                'message': message,
                'data': data
            }
            
            self.log_counter += 1
            self.log_entries.append(log_entry)
            self.utils_stats['logs_written'] += 1
            
            # 保持日志数量
            if len(self.log_entries) > self.utils_config['max_log_entries']:
                self.log_entries.pop(0)
                
            # 打印到控制台（根据日志级别）
            if self._should_print_log(level):
                print(f"[{level}] {message}")
                if data is not None:
                    print(f"  Data: {data}")
                    
        except Exception as e:
            print(f"✗ 日志记录失败: {e}")
            
    def _should_print_log(self, level: str) -> bool:
        """
        判断是否应该打印日志
        
        Args:
            level: 日志级别
            
        Returns:
            是否应该打印
        """
        try:
            level_order = {'DEBUG': 0, 'INFO': 1, 'WARNING': 2, 'ERROR': 3, 'CRITICAL': 4}
            current_level = self.utils_config['log_level']
            
            return level_order.get(level, 0) >= level_order.get(current_level, 1)
        except Exception:
            return True
            
    def get_log_entries(self, level: str = None, limit: int = None) -> List[Dict[str, Any]]:
        """
        获取日志条目
        
        Args:
            level: 日志级别过滤器
            limit: 返回条目数量限制
            
        Returns:
            日志条目列表
        """
        try:
            entries = self.log_entries.copy()
            
            if level:
                entries = [entry for entry in entries if entry['level'] == level]
                
            if limit:
                entries = entries[-limit:]
                
            return entries
        except Exception as e:
            print(f"✗ 日志条目获取失败: {e}")
            return []
            
    def clear_log_entries(self):
        """清空日志条目"""
        try:
            self.log_entries.clear()
            print("✓ 日志条目已清空")
        except Exception as e:
            print(f"✗ 日志条目清空失败: {e}")
            
    # 缓存工具函数
    def cache_set(self, key: str, value: Any, ttl: float = 300.0) -> bool:
        """
        设置缓存值
        
        Args:
            key: 缓存键
            value: 缓存值
            ttl: 生存时间（秒）
            
        Returns:
            是否设置成功
        """
        try:
            self.cache[key] = value
            self.cache_timestamps[key] = time.time() + ttl
            
            # 保持缓存大小
            if len(self.cache) > self.utils_config['cache_size']:
                oldest_key = min(self.cache_timestamps.keys(), key=lambda k: self.cache_timestamps[k])
                del self.cache[oldest_key]
                del self.cache_timestamps[oldest_key]
                
            return True
        except Exception as e:
            print(f"✗ 缓存设置失败: {e}")
            return False
            
    def cache_get(self, key: str, default: Any = None) -> Any:
        """
        获取缓存值
        
        Args:
            key: 缓存键
            default: 默认值
            
        Returns:
            缓存值或默认值
        """
        try:
            if key in self.cache:
                # 检查是否过期
                if time.time() < self.cache_timestamps.get(key, float('inf')):
                    self.utils_stats['cache_hits'] += 1
                    return self.cache[key]
                else:
                    # 过期，删除
                    del self.cache[key]
                    del self.cache_timestamps[key]
                    
            self.utils_stats['cache_misses'] += 1
            return default
        except Exception as e:
            print(f"✗ 缓存获取失败: {e}")
            self.utils_stats['cache_misses'] += 1
            return default
            
    def cache_clear(self):
        """清空缓存"""
        try:
            self.cache.clear()
            self.cache_timestamps.clear()
            print("✓ 缓存已清空")
        except Exception as e:
            print(f"✗ 缓存清空失败: {e}")
            
    # 数据转换工具函数
    def convert_angle(self, angle: float, from_unit: str = None, to_unit: str = None) -> float:
        """
        转换角度单位
        
        Args:
            angle: 角度值
            from_unit: 源单位（默认使用配置）
            to_unit: 目标单位（默认使用配置）
            
        Returns:
            转换后的角度值
        """
        try:
            if from_unit is None:
                from_unit = self.conversion_config['angle_unit']
            if to_unit is None:
                to_unit = self.conversion_config['angle_unit']
                
            # 如果单位相同，直接返回
            if from_unit == to_unit:
                return angle
                
            # 转换到弧度
            if from_unit == 'degrees':
                radians = math.radians(angle)
            else:
                radians = angle
                
            # 从弧度转换到目标单位
            if to_unit == 'degrees':
                result = math.degrees(radians)
            else:
                result = radians
                
            self.utils_stats['data_converted'] += 1
            return result
            
        except Exception as e:
            print(f"✗ 角度转换失败: {e}")
            return angle
            
    def convert_distance(self, distance: float, from_unit: str = None, to_unit: str = None) -> float:
        """
        转换距离单位
        
        Args:
            distance: 距离值
            from_unit: 源单位（默认使用配置）
            to_unit: 目标单位（默认使用配置）
            
        Returns:
            转换后的距离值
        """
        try:
            # 简化的距离转换（实际应用中可能需要更复杂的转换）
            # 这里假设像素和单位是相同的，米需要缩放因子
            return distance  # 简化处理
            
        except Exception as e:
            print(f"✗ 距离转换失败: {e}")
            return distance
            
    def convert_time(self, time_value: float, from_unit: str = None, to_unit: str = None) -> float:
        """
        转换时间单位
        
        Args:
            time_value: 时间值
            from_unit: 源单位（默认使用配置）
            to_unit: 目标单位（默认使用配置）
            
        Returns:
            转换后的时间值
        """
        try:
            if from_unit is None:
                from_unit = self.conversion_config['time_unit']
            if to_unit is None:
                to_unit = self.conversion_config['time_unit']
                
            # 如果单位相同，直接返回
            if from_unit == to_unit:
                return time_value
                
            # 转换到秒
            if from_unit == 'milliseconds':
                seconds = time_value / 1000.0
            else:
                seconds = time_value
                
            # 从秒转换到目标单位
            if to_unit == 'milliseconds':
                result = seconds * 1000.0
            else:
                result = seconds
                
            self.utils_stats['data_converted'] += 1
            return result
            
        except Exception as e:
            print(f"✗ 时间转换失败: {e}")
            return time_value
            
    # 数学工具函数
    def calculate_distance(self, point1: Tuple[float, float], point2: Tuple[float, float]) -> float:
        """
        计算两点间距离
        
        Args:
            point1: 第一个点 (x, y)
            point2: 第二个点 (x, y)
            
        Returns:
            距离值
        """
        try:
            dx = point2[0] - point1[0]
            dy = point2[1] - point1[1]
            return math.sqrt(dx*dx + dy*dy)
        except Exception as e:
            print(f"✗ 距离计算失败: {e}")
            return 0.0
            
    def calculate_angle(self, point1: Tuple[float, float], point2: Tuple[float, float]) -> float:
        """
        计算两点间角度
        
        Args:
            point1: 第一个点 (x, y)
            point2: 第二个点 (x, y)
            
        Returns:
            角度值（弧度）
        """
        try:
            dx = point2[0] - point1[0]
            dy = point2[1] - point1[1]
            return math.atan2(dy, dx)
        except Exception as e:
            print(f"✗ 角度计算失败: {e}")
            return 0.0
            
    def normalize_vector(self, vector: Tuple[float, float]) -> Tuple[float, float]:
        """
        归一化向量
        
        Args:
            vector: 向量 (x, y)
            
        Returns:
            归一化后的向量
        """
        try:
            length = math.sqrt(vector[0]*vector[0] + vector[1]*vector[1])
            if length > 0:
                return (vector[0]/length, vector[1]/length)
            else:
                return (0.0, 0.0)
        except Exception as e:
            print(f"✗ 向量归一化失败: {e}")
            return (0.0, 0.0)
            
    def clamp_value(self, value: float, min_value: float, max_value: float) -> float:
        """
        限制值范围
        
        Args:
            value: 值
            min_value: 最小值
            max_value: 最大值
            
        Returns:
            限制后的值
        """
        try:
            return max(min_value, min(max_value, value))
        except Exception as e:
            print(f"✗ 值限制失败: {e}")
            return value
            
    # JSON工具函数
    def safe_json_load(self, json_string: str, default_value: Any = None) -> Any:
        """
        安全地加载JSON字符串
        
        Args:
            json_string: JSON字符串
            default_value: 默认值
            
        Returns:
            解析后的数据或默认值
        """
        try:
            return json.loads(json_string)
        except Exception as e:
            print(f"✗ JSON加载失败: {e}")
            self.utils_stats['errors_handled'] += 1
            return default_value
            
    def safe_json_dump(self, data: Any, **kwargs) -> str:
        """
        安全地导出JSON数据
        
        Args:
            data: 要导出的数据
            **kwargs: json.dumps的其他参数
            
        Returns:
            JSON字符串
        """
        try:
            return json.dumps(data, **kwargs)
        except Exception as e:
            print(f"✗ JSON导出失败: {e}")
            self.utils_stats['errors_handled'] += 1
            return "{}"
            
    # 哈希工具函数
    def calculate_hash(self, data: Union[str, bytes], algorithm: str = 'md5') -> str:
        """
        计算数据哈希值
        
        Args:
            data: 要计算哈希的数据
            algorithm: 哈希算法 ('md5', 'sha1', 'sha256')
            
        Returns:
            哈希值十六进制字符串
        """
        try:
            if isinstance(data, str):
                data = data.encode('utf-8')
                
            if algorithm == 'md5':
                hash_obj = hashlib.md5()
            elif algorithm == 'sha1':
                hash_obj = hashlib.sha1()
            elif algorithm == 'sha256':
                hash_obj = hashlib.sha256()
            else:
                hash_obj = hashlib.md5()
                
            hash_obj.update(data)
            return hash_obj.hexdigest()
            
        except Exception as e:
            print(f"✗ 哈希计算失败: {e}")
            return ""
            
    # 性能工具函数
    def get_performance_metrics(self) -> Dict[str, Any]:
        """
        获取性能指标
        
        Returns:
            性能指标字典
        """
        try:
            metrics = self.performance_metrics.copy()
            
            # 计算平均更新时间
            if self.performance_metrics['update_times']:
                metrics['average_update_time'] = sum(self.performance_metrics['update_times']) / len(self.performance_metrics['update_times'])
            else:
                metrics['average_update_time'] = 0.0
                
            # 计算运行时间
            metrics['uptime'] = time.time() - self.startup_time
            
            return metrics
        except Exception as e:
            print(f"✗ 性能指标获取失败: {e}")
            return {}
            
    def reset_performance_metrics(self):
        """重置性能指标"""
        try:
            self.performance_metrics = {
                'update_times': [],
                'memory_usage': 0,
                'cpu_usage': 0,
                'frame_rate': 0.0,
                'last_sample_time': 0.0
            }
            print("✓ 性能指标已重置")
        except Exception as e:
            print(f"✗ 性能指标重置失败: {e}")
            
    # 配置工具函数
    def get_utils_config(self) -> Dict[str, Any]:
        """
        获取工具配置
        
        Returns:
            工具配置字典
        """
        return self.utils_config.copy()
        
    def set_utils_config(self, config: Dict[str, Any]) -> bool:
        """
        设置工具配置
        
        Args:
            config: 工具配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.utils_config.update(config)
            print(f"✓ 工具配置已更新: {self.utils_config}")
            return True
        except Exception as e:
            print(f"✗ 工具配置设置失败: {e}")
            return False
            
    def get_conversion_config(self) -> Dict[str, str]:
        """
        获取转换配置
        
        Returns:
            转换配置字典
        """
        return self.conversion_config.copy()
        
    def set_conversion_config(self, config: Dict[str, str]) -> bool:
        """
        设置转换配置
        
        Args:
            config: 转换配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.conversion_config.update(config)
            print(f"✓ 转换配置已更新: {self.conversion_config}")
            return True
        except Exception as e:
            print(f"✗ 转换配置设置失败: {e}")
            return False
            
    # 统计工具函数
    def get_utils_stats(self) -> Dict[str, int]:
        """
        获取工具统计信息
        
        Returns:
            工具统计字典
        """
        return self.utils_stats.copy()
        
    def reset_utils_stats(self):
        """重置工具统计信息"""
        try:
            self.utils_stats = {
                'functions_called': 0,
                'cache_hits': 0,
                'cache_misses': 0,
                'data_converted': 0,
                'logs_written': 0,
                'errors_handled': 0
            }
            print("✓ 工具统计信息已重置")
        except Exception as e:
            print(f"✗ 工具统计信息重置失败: {e}")
            
    # 调试工具函数
    def dump_object_info(self, obj: Any, name: str = "Object") -> str:
        """
        转储对象信息
        
        Args:
            obj: 要转储的对象
            name: 对象名称
            
        Returns:
            对象信息字符串
        """
        try:
            info = f"=== {name} Info ===\n"
            info += f"Type: {type(obj)}\n"
            info += f"String representation: {str(obj)}\n"
            
            if hasattr(obj, '__dict__'):
                info += f"Attributes: {obj.__dict__}\n"
                
            if hasattr(obj, '__slots__'):
                info += f"Slots: {obj.__slots__}\n"
                
            return info
        except Exception as e:
            print(f"✗ 对象信息转储失败: {e}")
            return f"Error dumping {name}: {e}"
            
    def measure_execution_time(self, func: callable, *args, **kwargs) -> Tuple[Any, float]:
        """
        测量函数执行时间
        
        Args:
            func: 要测量的函数
            *args: 函数参数
            **kwargs: 函数关键字参数
            
        Returns:
            (函数返回值, 执行时间)
        """
        try:
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            
            execution_time = end_time - start_time
            return result, execution_time
        except Exception as e:
            print(f"✗ 执行时间测量失败: {e}")
            return None, 0.0