"""
音频触觉反馈模块
负责将音频特征转换为触觉效果
"""

import time
from typing import Dict, Any, List, Optional
import math

class AudioHaptics:
    """
    音频触觉反馈
    负责将音频特征转换为触觉效果
    """
    
    def __init__(self, plugin):
        """
        初始化音频触觉反馈
        
        Args:
            plugin: 触觉反馈系统插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 音频分析配置
        self.audio_config = {
            'enable_audio_haptics': True,
            'analysis_rate': 30.0,  # Hz
            'frequency_bands': 8,
            'min_frequency': 20.0,
            'max_frequency': 20000.0,
            'intensity_scale': 1.0,
            'frequency_scale': 1.0,
            'smoothing_factor': 0.3
        }
        
        # 频带映射配置
        self.band_mapping = {
            'sub_bass': {'range': (20, 60), 'haptic_freq': 20.0, 'intensity': 1.0},
            'bass': {'range': (60, 250), 'haptic_freq': 30.0, 'intensity': 0.9},
            'low_mids': {'range': (250, 500), 'haptic_freq': 40.0, 'intensity': 0.7},
            'mids': {'range': (500, 2000), 'haptic_freq': 50.0, 'intensity': 0.5},
            'high_mids': {'range': (2000, 4000), 'haptic_freq': 60.0, 'intensity': 0.3},
            'presence': {'range': (4000, 6000), 'haptic_freq': 70.0, 'intensity': 0.2},
            'brilliance': {'range': (6000, 12000), 'haptic_freq': 80.0, 'intensity': 0.1},
            'air': {'range': (12000, 20000), 'haptic_freq': 90.0, 'intensity': 0.05}
        }
        
        # 节拍检测配置
        self.beat_config = {
            'enable_beat_detection': True,
            'min_bpm': 60,
            'max_bpm': 180,
            'sensitivity': 0.7,
            'history_size': 30
        }
        
        # 音频特征配置
        self.feature_config = {
            'enable_volume_haptics': True,
            'enable_spectral_haptics': True,
            'enable_temporal_haptics': True,
            'enable_rhythm_haptics': True
        }
        
        # 状态跟踪
        self.audio_state = {
            'last_analysis_time': 0.0,
            'current_features': {},
            'beat_history': [],
            'intensity_history': []
        }
        
        # 设备映射
        self.device_mapping = {
            'low_frequencies': 'body',     # 低频到身体设备
            'mid_frequencies': 'hands',    # 中频到手部设备
            'high_frequencies': 'fingers'  # 高频到手指设备
        }
        
        # 统计信息
        self.stats = {
            'audio_frames_analyzed': 0,
            'haptic_effects_generated': 0,
            'beats_detected': 0,
            'spectral_events': 0
        }
        
        # 回调函数
        self.audio_callbacks = {
            'audio_analyzed': [],
            'beat_detected': [],
            'feature_extracted': [],
            'haptic_effect_generated': []
        }
        
        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.audio_state.clear()
            self.audio_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
                
            # 检查是否需要进行音频分析
            current_time = time.time()
            analysis_interval = 1.0 / self.audio_config['analysis_rate']
            
            if current_time - self.audio_state['last_analysis_time'] >= analysis_interval:
                # 模拟音频分析
                self._analyze_audio_frame()
                self.audio_state['last_analysis_time'] = current_time
                
        except Exception as e:
            print(f"✗ 音频触觉反馈更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _analyze_audio_frame(self):
        """分析音频帧并生成触觉效果"""
        try:
            if not self.enabled or not self.audio_config['enable_audio_haptics']:
                return
                
            # 模拟音频特征提取
            audio_features = self._extract_audio_features()
            
            # 更新当前特征
            self.audio_state['current_features'] = audio_features
            
            # 触发音频分析回调
            self._trigger_audio_callback('audio_analyzed', {
                'features': audio_features,
                'timestamp': time.time()
            })
            
            # 处理音频特征并生成触觉效果
            self._process_audio_features(audio_features)
            
            # 检测节拍
            if self.beat_config['enable_beat_detection']:
                self._detect_beat(audio_features)
                
            self.stats['audio_frames_analyzed'] += 1
            
        except Exception as e:
            print(f"✗ 音频帧分析失败: {e}")
            
    def _extract_audio_features(self) -> Dict[str, Any]:
        """
        提取音频特征
        
        Returns:
            音频特征字典
        """
        try:
            # 模拟音频特征提取
            features = {
                'timestamp': time.time(),
                'rms': 0.5 + 0.5 * math.sin(time.time()),  # 模拟音量
                'spectral_centroid': 5000.0,  # 模拟频谱质心
                'spectral_rolloff': 10000.0,  # 模拟频谱滚降点
                'zero_crossing_rate': 0.1,     # 模拟过零率
                'temporal_flux': 0.3,          # 模拟时间通量
                'bpm': 120.0                   # 模拟节拍
            }
            
            # 生成频带能量（模拟）
            band_energies = []
            for i in range(self.audio_config['frequency_bands']):
                energy = 0.3 + 0.7 * math.sin(time.time() + i * 0.5)
                band_energies.append(max(0.0, min(1.0, energy)))
                
            features['band_energies'] = band_energies
            
            # 触发特征提取回调
            self._trigger_audio_callback('feature_extracted', {
                'features': features
            })
            
            return features
            
        except Exception as e:
            print(f"✗ 音频特征提取失败: {e}")
            return {}
            
    def _process_audio_features(self, features: Dict[str, Any]):
        """
        处理音频特征并生成触觉效果
        
        Args:
            features: 音频特征字典
        """
        try:
            if not features:
                return
                
            # 处理频带能量
            if self.feature_config['enable_spectral_haptics']:
                self._process_spectral_features(features)
                
            # 处理音量
            if self.feature_config['enable_volume_haptics']:
                self._process_volume_features(features)
                
            # 处理时间特征
            if self.feature_config['enable_temporal_haptics']:
                self._process_temporal_features(features)
                
        except Exception as e:
            print(f"✗ 音频特征处理失败: {e}")
            
    def _process_spectral_features(self, features: Dict[str, Any]):
        """
        处理频谱特征并生成触觉效果
        
        Args:
            features: 音频特征字典
        """
        try:
            band_energies = features.get('band_energies', [])
            
            for i, energy in enumerate(band_energies):
                if energy > 0.1:  # 能量阈值
                    # 获取频带信息
                    band_names = list(self.band_mapping.keys())
                    if i < len(band_names):
                        band_name = band_names[i]
                        band_info = self.band_mapping[band_name]
                        
                        # 计算触觉效果参数
                        intensity = energy * band_info['intensity'] * self.audio_config['intensity_scale']
                        frequency = band_info['haptic_freq'] * self.audio_config['frequency_scale']
                        duration = 0.05 + energy * 0.1  # 基于能量的持续时间
                        
                        # 确定目标设备
                        device_type = self._map_frequency_to_device(band_info['haptic_freq'])
                        device_id = self._get_device_id_by_type(device_type)
                        
                        # 生成触觉效果
                        self._generate_haptic_effect(
                            effect_type='periodic',
                            device_id=device_id,
                            intensity=intensity,
                            frequency=frequency,
                            duration=duration,
                            parameters={
                                'source': 'spectral',
                                'band': band_name,
                                'energy': energy
                            }
                        )
                        
                        self.stats['spectral_events'] += 1
                        
        except Exception as e:
            print(f"✗ 频谱特征处理失败: {e}")
            
    def _process_volume_features(self, features: Dict[str, Any]):
        """
        处理音量特征并生成触觉效果
        
        Args:
            features: 音频特征字典
        """
        try:
            rms = features.get('rms', 0.0)
            
            if rms > 0.05:  # 音量阈值
                # 计算触觉效果参数
                intensity = rms * self.audio_config['intensity_scale']
                frequency = 20.0 + rms * 30.0  # 基于音量的频率
                duration = 0.02  # 短持续时间以保持响应性
                
                # 生成触觉效果
                self._generate_haptic_effect(
                    effect_type='periodic',
                    device_id=None,  # 所有设备
                    intensity=intensity,
                    frequency=frequency,
                    duration=duration,
                    parameters={
                        'source': 'volume',
                        'rms': rms
                    }
                )
                
        except Exception as e:
            print(f"✗ 音量特征处理失败: {e}")
            
    def _process_temporal_features(self, features: Dict[str, Any]):
        """
        处理时间特征并生成触觉效果
        
        Args:
            features: 音频特征字典
        """
        try:
            temporal_flux = features.get('temporal_flux', 0.0)
            
            if temporal_flux > 0.2:  # 变化阈值
                # 计算触觉效果参数
                intensity = temporal_flux * self.audio_config['intensity_scale']
                frequency = 40.0 + temporal_flux * 40.0
                duration = 0.03 + temporal_flux * 0.07
                
                # 生成触觉效果
                self._generate_haptic_effect(
                    effect_type='noise',
                    device_id=None,
                    intensity=intensity,
                    frequency=frequency,
                    duration=duration,
                    parameters={
                        'source': 'temporal',
                        'flux': temporal_flux
                    }
                )
                
        except Exception as e:
            print(f"✗ 时间特征处理失败: {e}")
            
    def _detect_beat(self, features: Dict[str, Any]):
        """
        检测节拍并生成触觉效果
        
        Args:
            features: 音频特征字典
        """
        try:
            if not self.beat_config['enable_beat_detection']:
                return
                
            # 添加到节拍历史
            timestamp = features.get('timestamp', time.time())
            rms = features.get('rms', 0.0)
            
            self.audio_state['beat_history'].append({
                'timestamp': timestamp,
                'energy': rms
            })
            
            # 保持历史记录大小
            if len(self.audio_state['beat_history']) > self.beat_config['history_size']:
                self.audio_state['beat_history'].pop(0)
                
            # 检测节拍（简化实现）
            if len(self.audio_state['beat_history']) > 2:
                current_energy = self.audio_state['beat_history'][-1]['energy']
                previous_energy = self.audio_state['beat_history'][-2]['energy']
                
                # 简单的能量峰值检测
                if current_energy > previous_energy * (1.0 + self.beat_config['sensitivity']):
                    # 生成节拍触觉效果
                    self._generate_haptic_effect(
                        effect_type='impulse',
                        device_id=None,
                        intensity=current_energy * self.audio_config['intensity_scale'],
                        frequency=60.0,
                        duration=0.05,
                        parameters={
                            'source': 'beat',
                            'energy': current_energy
                        }
                    )
                    
                    # 触发节拍检测回调
                    self._trigger_audio_callback('beat_detected', {
                        'timestamp': timestamp,
                        'energy': current_energy
                    })
                    
                    self.stats['beats_detected'] += 1
                    
        except Exception as e:
            print(f"✗ 节拍检测失败: {e}")
            
    def _map_frequency_to_device(self, frequency: float) -> str:
        """
        将频率映射到设备类型
        
        Args:
            frequency: 频率值
            
        Returns:
            设备类型
        """
        try:
            if frequency < 40.0:
                return 'body'
            elif frequency < 80.0:
                return 'hands'
            else:
                return 'fingers'
        except Exception as e:
            print(f"✗ 频率到设备映射失败: {e}")
            return 'hands'
            
    def _get_device_id_by_type(self, device_type: str) -> Optional[int]:
        """
        根据设备类型获取设备ID
        
        Args:
            device_type: 设备类型
            
        Returns:
            设备ID或None
        """
        try:
            if not self.plugin.device_manager:
                return None
                
            # 查找匹配类型的设备
            devices = self.plugin.device_manager.get_devices_by_type(device_type)
            if devices:
                return devices[0]['id']  # 返回第一个匹配的设备
                
            return None
        except Exception as e:
            print(f"✗ 设备ID获取失败: {e}")
            return None
            
    def _generate_haptic_effect(self, effect_type: str, device_id: Optional[int],
                              intensity: float, frequency: float, duration: float,
                              parameters: Dict[str, Any]) -> bool:
        """
        生成触觉效果
        
        Args:
            effect_type: 效果类型
            device_id: 设备ID
            intensity: 强度
            frequency: 频率
            duration: 持续时间
            parameters: 参数
            
        Returns:
            是否生成成功
        """
        try:
            if not self.plugin.haptic_manager:
                return False
                
            # 限制参数范围
            intensity = max(0.0, min(1.0, intensity))
            frequency = max(1.0, min(100.0, frequency))
            duration = max(0.01, min(2.0, duration))
            
            # 生成触觉效果
            effect_id = self.plugin.haptic_manager.play_effect(
                effect_type=effect_type,
                device_id=device_id,
                intensity=intensity,
                duration=duration,
                frequency=frequency,
                parameters=parameters
            )
            
            if effect_id >= 0:
                # 触发效果生成回调
                self._trigger_audio_callback('haptic_effect_generated', {
                    'effect_id': effect_id,
                    'effect_type': effect_type,
                    'intensity': intensity,
                    'frequency': frequency,
                    'duration': duration,
                    'parameters': parameters
                })
                
                self.stats['haptic_effects_generated'] += 1
                return True
                
            return False
            
        except Exception as e:
            print(f"✗ 触觉效果生成失败: {e}")
            return False
            
    def _trigger_audio_callback(self, callback_type: str, data: Dict[str, Any]):
        """
        触发音频回调
        
        Args:
            callback_type: 回调类型
            data: 回调数据
        """
        try:
            if callback_type in self.audio_callbacks:
                for callback in self.audio_callbacks[callback_type]:
                    try:
                        callback(data)
                    except Exception as e:
                        print(f"✗ 音频回调执行失败: {e}")
        except Exception as e:
            print(f"✗ 音频回调触发失败: {e}")
            
    def register_audio_callback(self, callback_type: str, callback: callable):
        """
        注册音频回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.audio_callbacks:
                self.audio_callbacks[callback_type].append(callback)
                print(f"✓ 音频回调已注册: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 音频回调注册失败: {e}")
            
    def unregister_audio_callback(self, callback_type: str, callback: callable):
        """
        注销音频回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.audio_callbacks:
                if callback in self.audio_callbacks[callback_type]:
                    self.audio_callbacks[callback_type].remove(callback)
                    print(f"✓ 音频回调已注销: {callback_type}")
        except Exception as e:
            print(f"✗ 音频回调注销失败: {e}")
            
    def set_audio_config(self, config: Dict[str, Any]) -> bool:
        """
        设置音频配置
        
        Args:
            config: 配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.audio_config.update(config)
            print(f"✓ 音频配置已更新: {self.audio_config}")
            return True
        except Exception as e:
            print(f"✗ 音频配置设置失败: {e}")
            return False
            
    def set_band_mapping(self, mapping: Dict[str, Dict[str, Any]]) -> bool:
        """
        设置频带映射
        
        Args:
            mapping: 映射字典
            
        Returns:
            是否设置成功
        """
        try:
            self.band_mapping.update(mapping)
            print(f"✓ 频带映射已更新")
            return True
        except Exception as e:
            print(f"✗ 频带映射设置失败: {e}")
            return False
            
    def set_beat_config(self, config: Dict[str, Any]) -> bool:
        """
        设置节拍检测配置
        
        Args:
            config: 配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.beat_config.update(config)
            print(f"✓ 节拍检测配置已更新: {self.beat_config}")
            return True
        except Exception as e:
            print(f"✗ 节拍检测配置设置失败: {e}")
            return False
            
    def get_audio_config(self) -> Dict[str, Any]:
        """
        获取音频配置
        
        Returns:
            配置字典
        """
        return self.audio_config.copy()
        
    def get_band_mapping(self) -> Dict[str, Dict[str, Any]]:
        """
        获取频带映射
        
        Returns:
            映射字典
        """
        return self.band_mapping.copy()
        
    def get_beat_config(self) -> Dict[str, Any]:
        """
        获取节拍检测配置
        
        Returns:
            配置字典
        """
        return self.beat_config.copy()
        
    def get_stats(self) -> Dict[str, int]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        try:
            self.stats = {
                'audio_frames_analyzed': 0,
                'haptic_effects_generated': 0,
                'beats_detected': 0,
                'spectral_events': 0
            }
            print("✓ 音频触觉反馈统计信息已重置")
        except Exception as e:
            print(f"✗ 音频触觉反馈统计信息重置失败: {e}")