"""
工具类模块
提供触觉反馈系统所需的实用工具函数
"""

import time
import math
from typing import Dict, Any, List, Optional, Union
import threading
import json

class HapticUtils:
    """
    触觉工具类
    提供触觉反馈系统所需的实用工具函数
    """
    
    def __init__(self, plugin):
        """
        初始化触觉工具类
        
        Args:
            plugin: 触觉反馈系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 性能监控
        self.performance_metrics = {
            'update_times': [],
            'effect_processing_times': [],
            'device_response_times': [],
            'memory_usage': 0
        }
        
        # 日志配置
        self.log_config = {
            'enable_logging': True,
            'log_level': 'INFO',
            'log_file': '/home/hello/EG/plugins/user/haptic_feedback_system/logs/haptic.log',
            'max_log_size': 10 * 1024 * 1024,  # 10MB
            'log_format': '[{timestamp}] {level}: {message}'
        }
        
        # 数据转换配置
        self.conversion_config = {
            'intensity_curve': 'linear',  # linear, exponential, logarithmic
            'frequency_mapping': 'linear',
            'duration_scaling': 'linear'
        }
        
        # 数学工具
        self.math_utils = MathUtils()
        
        # 缓存管理
        self.cache_manager = CacheManager()
        
        # 调试工具
        self.debug_tools = DebugTools()
        
        # 统计信息
        self.stats = {
            'functions_called': 0,
            'data_processed': 0,
            'cache_hits': 0,
            'cache_misses': 0
        }
        
        print("✓ 触觉工具类已创建")
        
    def initialize(self) -> bool:
        """
        初始化触觉工具类
        
        Returns:
            是否初始化成功
        """
        try:
            # 创建日志目录
            import os
            log_dir = "/home/hello/EG/plugins/user/haptic_feedback_system/logs"
            os.makedirs(log_dir, exist_ok=True)
            
            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.performance_metrics.clear()
            self.cache_manager.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._update_performance_metrics(dt)
            
        except Exception as e:
            print(f"✗ 触觉工具类更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_performance_metrics(self, dt: float):
        """更新性能指标"""
        try:
            # 记录更新时间
            self.performance_metrics['update_times'].append(dt)
            
            # 保持历史记录大小
            if len(self.performance_metrics['update_times']) > 1000:
                self.performance_metrics['update_times'] = self.performance_metrics['update_times'][-1000:]
                
        except Exception as e:
            print(f"✗ 性能指标更新失败: {e}")
            
    def log_message(self, message: str, level: str = 'INFO'):
        """
        记录日志消息
        
        Args:
            message: 日志消息
            level: 日志级别 (DEBUG, INFO, WARNING, ERROR)
        """
        try:
            if not self.log_config['enable_logging']:
                return
                
            # 检查日志级别
            level_priority = {'DEBUG': 0, 'INFO': 1, 'WARNING': 2, 'ERROR': 3}
            config_level = self.log_config['log_level']
            
            if level_priority.get(level, 1) < level_priority.get(config_level, 1):
                return
                
            # 格式化日志消息
            timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
            formatted_message = self.log_config['log_format'].format(
                timestamp=timestamp,
                level=level,
                message=message
            )
            
            # 输出到控制台
            print(formatted_message)
            
            # 写入日志文件
            try:
                with open(self.log_config['log_file'], 'a', encoding='utf-8') as f:
                    f.write(formatted_message + '\n')
            except Exception as e:
                pass  # 忽略文件写入错误
                
        except Exception as e:
            pass  # 忽略日志记录错误
            
    def measure_performance(self, func: callable, *args, **kwargs) -> tuple:
        """
        测量函数性能
        
        Args:
            func: 要测量的函数
            *args: 函数参数
            **kwargs: 函数关键字参数
            
        Returns:
            (结果, 执行时间)
        """
        try:
            start_time = time.perf_counter()
            result = func(*args, **kwargs)
            end_time = time.perf_counter()
            
            execution_time = end_time - start_time
            
            # 记录到性能指标
            metric_name = f"{func.__name__}_times"
            if metric_name not in self.performance_metrics:
                self.performance_metrics[metric_name] = []
                
            self.performance_metrics[metric_name].append(execution_time)
            
            # 保持历史记录大小
            if len(self.performance_metrics[metric_name]) > 1000:
                self.performance_metrics[metric_name] = self.performance_metrics[metric_name][-1000:]
                
            self.stats['functions_called'] += 1
            return (result, execution_time)
            
        except Exception as e:
            self.log_message(f"性能测量失败: {e}", 'ERROR')
            raise
            
    def convert_intensity(self, intensity: float, curve: str = None) -> float:
        """
        转换强度值
        
        Args:
            intensity: 原始强度值 (0.0-1.0)
            curve: 转换曲线类型
            
        Returns:
            转换后的强度值
        """
        try:
            curve_type = curve or self.conversion_config['intensity_curve']
            intensity = max(0.0, min(1.0, intensity))
            
            if curve_type == 'exponential':
                # 指数曲线
                return math.pow(intensity, 2)
            elif curve_type == 'logarithmic':
                # 对数曲线
                return math.log(intensity + 1) / math.log(2)
            else:
                # 线性曲线
                return intensity
                
        except Exception as e:
            self.log_message(f"强度转换失败: {e}", 'ERROR')
            return intensity
            
    def convert_frequency(self, frequency: float, min_freq: float = 1.0, 
                         max_freq: float = 100.0, mapping: str = None) -> float:
        """
        转换频率值
        
        Args:
            frequency: 原始频率值
            min_freq: 最小频率
            max_freq: 最大频率
            mapping: 映射类型
            
        Returns:
            转换后的频率值
        """
        try:
            mapping_type = mapping or self.conversion_config['frequency_mapping']
            frequency = max(0.0, frequency)
            
            if mapping_type == 'logarithmic':
                # 对数映射
                log_min = math.log(max(min_freq, 1.0))
                log_max = math.log(max(max_freq, 1.0))
                log_freq = math.log(max(frequency, 1.0))
                normalized = (log_freq - log_min) / (log_max - log_min)
                return min_freq + normalized * (max_freq - min_freq)
            else:
                # 线性映射
                return max(min_freq, min(max_freq, frequency))
                
        except Exception as e:
            self.log_message(f"频率转换失败: {e}", 'ERROR')
            return frequency
            
    def scale_duration(self, duration: float, scale_factor: float = 1.0,
                      scaling_type: str = None) -> float:
        """
        缩放持续时间
        
        Args:
            duration: 原始持续时间
            scale_factor: 缩放因子
            scaling_type: 缩放类型
            
        Returns:
            缩放后的持续时间
        """
        try:
            scaling = scaling_type or self.conversion_config['duration_scaling']
            duration = max(0.0, duration)
            scale_factor = max(0.0, scale_factor)
            
            if scaling == 'exponential':
                return duration * math.pow(scale_factor, 2)
            elif scaling == 'logarithmic':
                return duration * math.log(scale_factor + 1)
            else:
                return duration * scale_factor
                
        except Exception as e:
            self.log_message(f"持续时间缩放失败: {e}", 'ERROR')
            return duration
            
    def interpolate_values(self, start_value: float, end_value: float, 
                          progress: float, interpolation_type: str = 'linear') -> float:
        """
        插值计算
        
        Args:
            start_value: 起始值
            end_value: 结束值
            progress: 进度 (0.0-1.0)
            interpolation_type: 插值类型
            
        Returns:
            插值结果
        """
        try:
            progress = max(0.0, min(1.0, progress))
            
            if interpolation_type == 'ease_in':
                progress = math.pow(progress, 2)
            elif interpolation_type == 'ease_out':
                progress = 1.0 - math.pow(1.0 - progress, 2)
            elif interpolation_type == 'ease_in_out':
                progress = 0.5 * (1 - math.cos(progress * math.pi))
            # linear 为默认情况，无需特殊处理
                
            return start_value + (end_value - start_value) * progress
            
        except Exception as e:
            self.log_message(f"插值计算失败: {e}", 'ERROR')
            return start_value
            
    def calculate_distance(self, pos1: tuple, pos2: tuple) -> float:
        """
        计算两点间距离
        
        Args:
            pos1: 第一个点 (x, y, z)
            pos2: 第二个点 (x, y, z)
            
        Returns:
            距离值
        """
        try:
            dx = pos2[0] - pos1[0]
            dy = pos2[1] - pos1[1]
            dz = pos2[2] - pos1[2]
            return math.sqrt(dx*dx + dy*dy + dz*dz)
        except Exception as e:
            self.log_message(f"距离计算失败: {e}", 'ERROR')
            return 0.0
            
    def normalize_vector(self, vector: tuple) -> tuple:
        """
        归一化向量
        
        Args:
            vector: 输入向量 (x, y, z)
            
        Returns:
            归一化后的向量
        """
        try:
            magnitude = math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
            if magnitude > 0:
                return (vector[0]/magnitude, vector[1]/magnitude, vector[2]/magnitude)
            else:
                return (0, 0, 0)
        except Exception as e:
            self.log_message(f"向量归一化失败: {e}", 'ERROR')
            return (0, 0, 0)
            
    def get_performance_stats(self) -> Dict[str, Any]:
        """
        获取性能统计信息
        
        Returns:
            性能统计字典
        """
        try:
            stats = {}
            for key, times in self.performance_metrics.items():
                if times:
                    stats[key] = {
                        'count': len(times),
                        'average': sum(times) / len(times),
                        'min': min(times),
                        'max': max(times),
                        'total': sum(times)
                    }
            return stats
        except Exception as e:
            self.log_message(f"性能统计获取失败: {e}", 'ERROR')
            return {}
            
    def get_system_info(self) -> Dict[str, Any]:
        """
        获取系统信息
        
        Returns:
            系统信息字典
        """
        try:
            import platform
            import psutil
            
            return {
                'platform': platform.system(),
                'platform_version': platform.version(),
                'processor': platform.processor(),
                'cpu_count': psutil.cpu_count(),
                'memory_total': psutil.virtual_memory().total,
                'memory_available': psutil.virtual_memory().available,
                'plugin_version': getattr(self.plugin, 'version', 'unknown')
            }
        except Exception as e:
            self.log_message(f"系统信息获取失败: {e}", 'ERROR')
            return {}
            
    def get_stats(self) -> Dict[str, int]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        try:
            self.stats = {
                'functions_called': 0,
                'data_processed': 0,
                'cache_hits': 0,
                'cache_misses': 0
            }
            print("✓ 工具类统计信息已重置")
        except Exception as e:
            self.log_message(f"统计信息重置失败: {e}", 'ERROR')
            
    def set_log_config(self, config: Dict[str, Any]) -> bool:
        """
        设置日志配置
        
        Args:
            config: 日志配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.log_config.update(config)
            self.log_message(f"日志配置已更新: {self.log_config}", 'INFO')
            return True
        except Exception as e:
            self.log_message(f"日志配置设置失败: {e}", 'ERROR')
            return False
            
    def set_conversion_config(self, config: Dict[str, Any]) -> bool:
        """
        设置转换配置
        
        Args:
            config: 转换配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.conversion_config.update(config)
            self.log_message(f"转换配置已更新: {self.conversion_config}", 'INFO')
            return True
        except Exception as e:
            self.log_message(f"转换配置设置失败: {e}", 'ERROR')
            return False
            
    def get_cache_manager(self):
        """
        获取缓存管理器
        
        Returns:
            缓存管理器实例
        """
        return self.cache_manager
        
    def get_debug_tools(self):
        """
        获取调试工具
        
        Returns:
            调试工具实例
        """
        return self.debug_tools

class MathUtils:
    """数学工具类"""
    
    @staticmethod
    def clamp(value: float, min_value: float, max_value: float) -> float:
        """限制值在指定范围内"""
        return max(min_value, min(max_value, value))
        
    @staticmethod
    def lerp(start: float, end: float, t: float) -> float:
        """线性插值"""
        return start + (end - start) * t
        
    @staticmethod
    def smoothstep(edge0: float, edge1: float, x: float) -> float:
        """平滑插值"""
        t = MathUtils.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
        return t * t * (3.0 - 2.0 * t)

class CacheManager:
    """缓存管理器"""
    
    def __init__(self):
        self.cache = {}
        self.access_times = {}
        self.max_size = 1000
        
    def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        if key in self.cache:
            self.access_times[key] = time.time()
            return self.cache[key]
        return None
        
    def set(self, key: str, value: Any, ttl: float = 300.0):
        """设置缓存值"""
        self.cache[key] = value
        self.access_times[key] = time.time()
        
        # 检查缓存大小
        if len(self.cache) > self.max_size:
            self._cleanup()
            
    def _cleanup(self):
        """清理过期缓存"""
        current_time = time.time()
        expired_keys = [
            key for key, access_time in self.access_times.items()
            if current_time - access_time > 300.0
        ]
        
        for key in expired_keys:
            del self.cache[key]
            del self.access_times[key]
            
    def clear(self):
        """清空缓存"""
        self.cache.clear()
        self.access_times.clear()

class DebugTools:
    """调试工具类"""
    
    def __init__(self):
        self.debug_enabled = False
        self.debug_data = {}
        
    def enable_debug(self):
        """启用调试模式"""
        self.debug_enabled = True
        
    def disable_debug(self):
        """禁用调试模式"""
        self.debug_enabled = False
        
    def log_debug_data(self, key: str, data: Any):
        """记录调试数据"""
        if self.debug_enabled:
            self.debug_data[key] = data
            
    def get_debug_data(self, key: str = None) -> Union[Dict[str, Any], Any]:
        """获取调试数据"""
        if key:
            return self.debug_data.get(key)
        return self.debug_data.copy()
        
    def clear_debug_data(self):
        """清空调试数据"""
        self.debug_data.clear()