"""
调制效果处理器
实现专业的音频调制效果处理（合唱、镶边、移相等）
"""

import uuid
import math
import numpy as np
from typing import Dict, List, Any, Optional

class ModulationProcessor:
    """
    调制效果处理器
    实现专业的音频调制效果处理（合唱、镶边、移相等）
    """
    
    def __init__(self, plugin):
        """
        初始化调制效果处理器
        
        Args:
            plugin: 音频效果插件实例
        """
        self.plugin = plugin
        self.effects: Dict[str, Dict[str, Any]] = {}
        self.stats = {
            'total_effects': 0,
            'active_effects': 0,
            'effects_processed': 0,
            'processing_time': 0.0,
            'memory_usage': 0
        }
        self.buffer_size = plugin.buffer_size if plugin else 4096
        self.sample_rate = 44100  # 默认采样率
        
    def create_effect(self, parameters: Dict[str, Any]) -> str:
        """
        创建调制效果
        
        Args:
            parameters: 调制效果参数
            
        Returns:
            效果ID
        """
        try:
            # 生成唯一ID
            effect_id = str(uuid.uuid4())
            
            # 默认参数
            default_params = {
                'type': 'chorus',      # 效果类型: chorus, flanger, phaser
                'rate': 1.0,          # 速率 (Hz)
                'depth': 0.5,         # 深度 (0.0-1.0)
                'feedback': 0.3,      # 反馈 (-1.0-1.0)
                'mix': 0.5,           # 湿信号混合 (0.0-1.0)
                'delay': 0.002,       # 延迟时间 (秒)
                'center_delay': 0.002, # 中心延迟 (秒)
                'spread': 0.5,        # 扩散 (0.0-1.0)
                'stereo': True,       # 立体声
                'lfo_waveform': 'sine', # LFO波形: sine, triangle, square, sawtooth
                'lfo_phase': 0.0,     # LFO相位 (度)
                'high_cut': 8000.0,   # 高频截止 (Hz)
                'low_cut': 100.0      # 低频截止 (Hz)
            }
            
            # 合并参数
            effect_params = default_params.copy()
            effect_params.update(parameters)
            
            # 创建效果对象
            effect = {
                'id': effect_id,
                'type': 'modulation',
                'parameters': effect_params,
                'active': True,
                'buffers': {},  # 缓冲区
                'lfo_phase': 0.0,  # LFO相位状态
                'delay_buffers': {},  # 延迟缓冲区
                'filter_states': {},  # 滤波器状态
                'created_time': self._get_current_time(),
                'process_count': 0
            }
            
            # 初始化缓冲区
            self._initialize_buffers(effect)
            
            # 存储效果
            self.effects[effect_id] = effect
            
            # 更新统计信息
            self.stats['total_effects'] += 1
            self.stats['active_effects'] += 1
            
            # 在插件中注册效果
            if self.plugin:
                self.plugin.effects[effect_id] = effect.copy()
            
            print(f"✓ 调制效果创建成功: {effect_id}")
            return effect_id
            
        except Exception as e:
            print(f"✗ 创建调制效果失败: {e}")
            import traceback
            traceback.print_exc()
            return ""
            
    def _initialize_buffers(self, effect: Dict[str, Any]):
        """
        初始化缓冲区
        
        Args:
            effect: 效果对象
        """
        effect_id = effect['id']
        parameters = effect['parameters']
        buffers = {}
        
        # 输入和输出缓冲区
        buffers['input'] = np.zeros(self.buffer_size)
        buffers['output'] = np.zeros(self.buffer_size)
        
        # 延迟缓冲区
        max_delay_samples = int(0.1 * self.sample_rate)  # 最大100ms延迟
        buffers['delay_line'] = np.zeros(max_delay_samples)
        buffers['delay_index'] = 0
        
        # 立体声延迟缓冲区
        if parameters.get('stereo', True):
            buffers['delay_line_right'] = np.zeros(max_delay_samples)
            buffers['delay_index_right'] = 0
            
        # 滤波器状态
        buffers['high_pass_state'] = np.zeros(2)  # 双通道高通滤波器状态
        buffers['low_pass_state'] = np.zeros(2)   # 双通道低通滤波器状态
        
        effect['buffers'] = buffers
        
    def delete_effect(self, effect_id: str) -> bool:
        """
        删除调制效果
        
        Args:
            effect_id: 效果ID
            
        Returns:
            是否删除成功
        """
        if effect_id not in self.effects:
            print(f"✗ 调制效果不存在: {effect_id}")
            return False
            
        try:
            # 删除效果
            del self.effects[effect_id]
            
            # 更新统计信息
            self.stats['active_effects'] -= 1
            
            # 从插件中移除效果
            if self.plugin and effect_id in self.plugin.effects:
                del self.plugin.effects[effect_id]
            
            print(f"✓ 调制效果已删除: {effect_id}")
            return True
            
        except Exception as e:
            print(f"✗ 删除调制效果失败: {e}")
            return False
            
    def process(self, audio_data: Any, parameters: Dict[str, Any]) -> Any:
        """
        处理调制效果
        
        Args:
            audio_data: 输入音频数据
            parameters: 效果参数
            
        Returns:
            处理后的音频数据
        """
        try:
            import time
            process_start = time.time()
            
            # 如果输入是NumPy数组
            if isinstance(audio_data, np.ndarray):
                processed_data = self._process_numpy_array(audio_data, parameters)
            else:
                # 对于其他类型的数据，返回原始数据
                processed_data = audio_data
                
            # 更新统计信息
            self.stats['effects_processed'] += 1
            self.stats['processing_time'] += (time.time() - process_start)
            
            return processed_data
            
        except Exception as e:
            print(f"✗ 调制效果处理失败: {e}")
            return audio_data
            
    def _process_numpy_array(self, audio_data: np.ndarray, parameters: Dict[str, Any]) -> np.ndarray:
        """
        处理NumPy数组音频数据
        
        Args:
            audio_data: 输入音频数据
            parameters: 效果参数
            
        Returns:
            处理后的音频数据
        """
        # 获取参数
        effect_type = parameters.get('type', 'chorus')
        rate = max(0.01, min(10.0, parameters.get('rate', 1.0)))
        depth = max(0.0, min(1.0, parameters.get('depth', 0.5)))
        feedback = max(-1.0, min(1.0, parameters.get('feedback', 0.3)))
        mix = max(0.0, min(1.0, parameters.get('mix', 0.5)))
        delay = max(0.0001, min(0.05, parameters.get('delay', 0.002)))
        center_delay = max(0.0001, min(0.05, parameters.get('center_delay', 0.002)))
        spread = max(0.0, min(1.0, parameters.get('spread', 0.5)))
        stereo = parameters.get('stereo', True)
        lfo_waveform = parameters.get('lfo_waveform', 'sine')
        high_cut = max(100.0, min(20000.0, parameters.get('high_cut', 8000.0)))
        low_cut = max(20.0, min(10000.0, parameters.get('low_cut', 100.0)))
        
        # 创建输出数组
        if audio_data.ndim == 1:
            # 单声道处理
            output_data = np.zeros_like(audio_data)
            
            # 初始化LFO相位
            lfo_phase = 0.0
            lfo_increment = 2.0 * math.pi * rate / self.sample_rate
            
            for i in range(len(audio_data)):
                sample = audio_data[i]
                
                # 生成LFO值
                lfo_value = self._generate_lfo_value(lfo_waveform, lfo_phase)
                
                # 计算调制延迟
                if effect_type == 'chorus':
                    mod_delay = center_delay + depth * 0.005 * lfo_value
                elif effect_type == 'flanger':
                    mod_delay = delay + depth * 0.005 * lfo_value
                else:  # phaser
                    mod_delay = delay
                
                # 限制延迟范围
                mod_delay = max(0.0001, min(0.05, mod_delay))
                
                # 读取延迟样本（简化插值）
                delayed_sample = self._read_delayed_sample(sample, mod_delay, feedback)
                
                # 应用滤波器（如果是镶边或移相器）
                if effect_type in ['flanger', 'phaser']:
                    delayed_sample = self._apply_filter(delayed_sample, high_cut, low_cut)
                
                # 混合干湿信号
                output_data[i] = sample * (1.0 - mix) + delayed_sample * mix
                
                # 更新LFO相位
                lfo_phase += lfo_increment
                if lfo_phase >= 2.0 * math.pi:
                    lfo_phase -= 2.0 * math.pi
                    
        else:
            # 多声道处理（立体声）
            output_data = np.zeros_like(audio_data)
            
            # 初始化LFO相位
            lfo_phase_left = 0.0
            lfo_phase_right = parameters.get('lfo_phase', 0.0) * math.pi / 180.0  # 转换为弧度
            lfo_increment = 2.0 * math.pi * rate / self.sample_rate
            
            for channel in range(min(2, audio_data.shape[0])):  # 最多处理两个声道
                lfo_phase = lfo_phase_left if channel == 0 else lfo_phase_right
                
                for i in range(audio_data.shape[1]):
                    sample = audio_data[channel, i]
                    
                    # 生成LFO值
                    lfo_value = self._generate_lfo_value(lfo_waveform, lfo_phase)
                    
                    # 计算调制延迟
                    if effect_type == 'chorus':
                        if channel == 0:  # 左声道
                            mod_delay = center_delay + depth * 0.005 * lfo_value * (1.0 - spread)
                        else:  # 右声道
                            mod_delay = center_delay + depth * 0.005 * lfo_value * (1.0 + spread)
                    elif effect_type == 'flanger':
                        mod_delay = delay + depth * 0.005 * lfo_value
                    else:  # phaser
                        mod_delay = delay
                    
                    # 限制延迟范围
                    mod_delay = max(0.0001, min(0.05, mod_delay))
                    
                    # 读取延迟样本（简化插值）
                    delayed_sample = self._read_delayed_sample(sample, mod_delay, feedback)
                    
                    # 应用滤波器（如果是镶边或移相器）
                    if effect_type in ['flanger', 'phaser']:
                        delayed_sample = self._apply_filter(delayed_sample, high_cut, low_cut)
                    
                    # 混合干湿信号
                    output_data[channel, i] = sample * (1.0 - mix) + delayed_sample * mix
                    
                    # 更新LFO相位
                    lfo_phase += lfo_increment
                    if lfo_phase >= 2.0 * math.pi:
                        lfo_phase -= 2.0 * math.pi
                        
        # 确保输出在有效范围内
        processed_data = np.clip(output_data, -1.0, 1.0)
        return processed_data
        
    def _generate_lfo_value(self, waveform: str, phase: float) -> float:
        """
        生成LFO值
        
        Args:
            waveform: 波形类型
            phase: 相位（弧度）
            
        Returns:
            LFO值 (-1.0 到 1.0)
        """
        if waveform == 'sine':
            return math.sin(phase)
        elif waveform == 'triangle':
            # 三角波
            normalized_phase = phase / (2.0 * math.pi)
            if normalized_phase < 0.25:
                return 4.0 * normalized_phase
            elif normalized_phase < 0.75:
                return 2.0 - 4.0 * normalized_phase
            else:
                return 4.0 * normalized_phase - 4.0
        elif waveform == 'square':
            # 方波
            return 1.0 if math.sin(phase) >= 0.0 else -1.0
        elif waveform == 'sawtooth':
            # 锯齿波
            normalized_phase = phase / (2.0 * math.pi)
            return 2.0 * normalized_phase - 1.0
        else:
            # 默认使用正弦波
            return math.sin(phase)
            
    def _read_delayed_sample(self, input_sample: float, delay_time: float, feedback: float) -> float:
        """
        读取延迟样本
        
        Args:
            input_sample: 输入样本
            delay_time: 延迟时间（秒）
            feedback: 反馈系数
            
        Returns:
            延迟样本
        """
        # 这里使用简化的延迟处理
        # 实际应用中会使用更复杂的延迟线和插值
        
        # 计算延迟样本数
        delay_samples = delay_time * self.sample_rate
        
        # 简化的延迟效果（使用单一样本延迟）
        delayed_sample = input_sample * 0.5  # 简化的延迟
        
        # 应用反馈
        if abs(feedback) > 0.01:
            delayed_sample += delayed_sample * feedback * 0.3
            
        return delayed_sample
        
    def _apply_filter(self, sample: float, high_cut: float, low_cut: float) -> float:
        """
        应用滤波器
        
        Args:
            sample: 输入样本
            high_cut: 高频截止频率
            low_cut: 低频截止频率
            
        Returns:
            滤波后的样本
        """
        # 这里使用简化的滤波器
        # 实际应用中会使用更复杂的滤波器设计
        
        # 简单的一阶滤波器
        filtered_sample = sample
        
        # 高频截止（低通滤波器效果）
        if high_cut < 10000.0:
            filter_factor = high_cut / 10000.0
            filtered_sample *= (0.5 + 0.5 * filter_factor)
            
        # 低频截止（高通滤波器效果）
        if low_cut > 100.0:
            filter_factor = low_cut / 10000.0
            filtered_sample *= (0.5 + 0.5 * filter_factor)
            
        return filtered_sample
        
    def set_parameter(self, effect_id: str, parameter: str, value: Any) -> bool:
        """
        设置效果参数
        
        Args:
            effect_id: 效果ID
            parameter: 参数名
            value: 参数值
            
        Returns:
            是否设置成功
        """
        if effect_id not in self.effects:
            print(f"✗ 调制效果不存在: {effect_id}")
            return False
            
        try:
            self.effects[effect_id]['parameters'][parameter] = value
            
            # 如果是插件中的效果，也更新插件中的副本
            if self.plugin and effect_id in self.plugin.effects:
                self.plugin.effects[effect_id]['parameters'][parameter] = value
                
            print(f"✓ 调制效果参数已设置: {effect_id}.{parameter} = {value}")
            return True
            
        except Exception as e:
            print(f"✗ 设置调制效果参数失败: {e}")
            return False
            
    def get_parameters(self, effect_id: str) -> Dict[str, Any]:
        """
        获取效果参数
        
        Args:
            effect_id: 效果ID
            
        Returns:
            参数字典
        """
        if effect_id not in self.effects:
            return {}
            
        return self.effects[effect_id]['parameters'].copy()
        
    def enable_effect(self, effect_id: str) -> bool:
        """
        启用调制效果
        
        Args:
            effect_id: 效果ID
            
        Returns:
            是否启用成功
        """
        if effect_id not in self.effects:
            print(f"✗ 调制效果不存在: {effect_id}")
            return False
            
        try:
            self.effects[effect_id]['active'] = True
            self.stats['active_effects'] += 1
            
            # 如果是插件中的效果，也更新插件中的副本
            if self.plugin and effect_id in self.plugin.effects:
                self.plugin.effects[effect_id]['active'] = True
                
            print(f"✓ 调制效果已启用: {effect_id}")
            return True
            
        except Exception as e:
            print(f"✗ 启用调制效果失败: {e}")
            return False
            
    def disable_effect(self, effect_id: str) -> bool:
        """
        禁用调制效果
        
        Args:
            effect_id: 效果ID
            
        Returns:
            是否禁用成功
        """
        if effect_id not in self.effects:
            print(f"✗ 调制效果不存在: {effect_id}")
            return False
            
        try:
            self.effects[effect_id]['active'] = False
            self.stats['active_effects'] -= 1
            
            # 如果是插件中的效果，也更新插件中的副本
            if self.plugin and effect_id in self.plugin.effects:
                self.plugin.effects[effect_id]['active'] = False
                
            print(f"✓ 调制效果已禁用: {effect_id}")
            return True
            
        except Exception as e:
            print(f"✗ 禁用调制效果失败: {e}")
            return False
            
    def cleanup(self):
        """清理所有资源"""
        self.effects.clear()
        self.stats = {
            'total_effects': 0,
            'active_effects': 0,
            'effects_processed': 0,
            'processing_time': 0.0,
            'memory_usage': 0
        }
        print("✓ 调制效果处理器资源已清理")
        
    def get_stats(self) -> Dict[str, int]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def _get_current_time(self) -> float:
        """
        获取当前时间（秒）
        
        Returns:
            当前时间
        """
        if self.plugin and self.plugin.plugin_manager and self.plugin.plugin_manager.world:
            return self.plugin.plugin_manager.world.globalClock.getFrameTime()
        import time
        return time.time()
        
    def update(self, dt: float):
        """
        更新处理器状态
        
        Args:
            dt: 时间增量
        """
        # 这里可以更新任何需要定期更新的状态
        pass
        
    def set_sample_rate(self, sample_rate: int):
        """
        设置采样率
        
        Args:
            sample_rate: 采样率 (Hz)
        """
        self.sample_rate = sample_rate
        print(f"✓ 调制效果处理器采样率已设置: {sample_rate} Hz")
        
    def set_rate(self, effect_id: str, rate: float) -> bool:
        """
        设置LFO速率
        
        Args:
            effect_id: 效果ID
            rate: 速率 (Hz)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'rate', max(0.01, min(10.0, rate)))
        
    def set_depth(self, effect_id: str, depth: float) -> bool:
        """
        设置深度
        
        Args:
            effect_id: 效果ID
            depth: 深度 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'depth', max(0.0, min(1.0, depth)))
        
    def set_feedback(self, effect_id: str, feedback: float) -> bool:
        """
        设置反馈
        
        Args:
            effect_id: 效果ID
            feedback: 反馈 (-1.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'feedback', max(-1.0, min(1.0, feedback)))
        
    def set_mix(self, effect_id: str, mix: float) -> bool:
        """
        设置湿信号混合
        
        Args:
            effect_id: 效果ID
            mix: 湿信号混合 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'mix', max(0.0, min(1.0, mix)))
        
    def set_delay(self, effect_id: str, delay: float) -> bool:
        """
        设置延迟时间
        
        Args:
            effect_id: 效果ID
            delay: 延迟时间 (秒)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'delay', max(0.0001, min(0.05, delay)))
        
    def set_center_delay(self, effect_id: str, delay: float) -> bool:
        """
        设置中心延迟时间
        
        Args:
            effect_id: 效果ID
            delay: 中心延迟时间 (秒)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'center_delay', max(0.0001, min(0.05, delay)))
        
    def set_spread(self, effect_id: str, spread: float) -> bool:
        """
        设置扩散
        
        Args:
            effect_id: 效果ID
            spread: 扩散 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'spread', max(0.0, min(1.0, spread)))
        
    def set_lfo_waveform(self, effect_id: str, waveform: str) -> bool:
        """
        设置LFO波形
        
        Args:
            effect_id: 效果ID
            waveform: 波形类型 (sine, triangle, square, sawtooth)
            
        Returns:
            是否设置成功
        """
        valid_waveforms = ['sine', 'triangle', 'square', 'sawtooth']
        if waveform not in valid_waveforms:
            print(f"✗ 无效的LFO波形: {waveform}")
            return False
            
        return self.set_parameter(effect_id, 'lfo_waveform', waveform)
        
    def enable_stereo(self, effect_id: str, enable: bool) -> bool:
        """
        启用/禁用立体声
        
        Args:
            effect_id: 效果ID
            enable: 是否启用
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'stereo', enable)
        
    def create_preset(self, preset_name: str) -> Dict[str, Any]:
        """
        创建调制效果预设
        
        Args:
            preset_name: 预设名称
            
        Returns:
            预设参数字典
        """
        presets = {
            'chorus_light': {
                'type': 'chorus',
                'rate': 0.8,
                'depth': 0.3,
                'feedback': 0.2,
                'mix': 0.4,
                'center_delay': 0.004,
                'spread': 0.3,
                'lfo_waveform': 'sine'
            },
            'chorus_medium': {
                'type': 'chorus',
                'rate': 1.2,
                'depth': 0.5,
                'feedback': 0.3,
                'mix': 0.6,
                'center_delay': 0.006,
                'spread': 0.5,
                'lfo_waveform': 'sine'
            },
            'chorus_heavy': {
                'type': 'chorus',
                'rate': 1.8,
                'depth': 0.7,
                'feedback': 0.4,
                'mix': 0.8,
                'center_delay': 0.008,
                'spread': 0.7,
                'lfo_waveform': 'triangle'
            },
            'flanger_light': {
                'type': 'flanger',
                'rate': 0.5,
                'depth': 0.4,
                'feedback': 0.5,
                'mix': 0.5,
                'delay': 0.001,
                'lfo_waveform': 'sine'
            },
            'flanger_medium': {
                'type': 'flanger',
                'rate': 0.8,
                'depth': 0.6,
                'feedback': 0.7,
                'mix': 0.7,
                'delay': 0.002,
                'lfo_waveform': 'sine'
            },
            'flanger_heavy': {
                'type': 'flanger',
                'rate': 1.2,
                'depth': 0.8,
                'feedback': 0.9,
                'mix': 0.9,
                'delay': 0.003,
                'lfo_waveform': 'triangle'
            },
            'phaser_light': {
                'type': 'phaser',
                'rate': 0.6,
                'depth': 0.3,
                'feedback': 0.2,
                'mix': 0.4,
                'delay': 0.0005,
                'lfo_waveform': 'sine',
                'high_cut': 6000.0,
                'low_cut': 200.0
            },
            'phaser_medium': {
                'type': 'phaser',
                'rate': 1.0,
                'depth': 0.5,
                'feedback': 0.4,
                'mix': 0.6,
                'delay': 0.001,
                'lfo_waveform': 'sine',
                'high_cut': 8000.0,
                'low_cut': 100.0
            },
            'phaser_heavy': {
                'type': 'phaser',
                'rate': 1.5,
                'depth': 0.7,
                'feedback': 0.6,
                'mix': 0.8,
                'delay': 0.002,
                'lfo_waveform': 'triangle',
                'high_cut': 10000.0,
                'low_cut': 50.0
            }
        }
        
        return presets.get(preset_name, {}).copy()
        
    def get_lfo_meter(self, effect_id: str) -> float:
        """
        获取LFO表
        
        Args:
            effect_id: 效果ID
            
        Returns:
            当前LFO值 (-1.0 到 1.0)
        """
        if effect_id not in self.effects:
            return 0.0
            
        effect = self.effects[effect_id]
        parameters = effect['parameters']
        lfo_waveform = parameters.get('lfo_waveform', 'sine')
        lfo_phase = effect.get('lfo_phase', 0.0)
        
        return self._generate_lfo_value(lfo_waveform, lfo_phase)
        
    def set_lfo_phase(self, effect_id: str, phase: float) -> bool:
        """
        设置LFO相位
        
        Args:
            effect_id: 效果ID
            phase: 相位 (度)
            
        Returns:
            是否设置成功
        """
        # 转换为弧度并规范化
        phase_rad = (phase * math.pi / 180.0) % (2.0 * math.pi)
        return self.set_parameter(effect_id, 'lfo_phase', phase)

