"""
失真效果处理器
实现专业的音频失真效果处理
"""

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

class DistortionProcessor:
    """
    失真效果处理器
    实现专业的音频失真效果处理
    """
    
    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 = {
                'drive': 0.5,         # 驱动 (0.0-1.0)
                'tone': 0.5,          # 音调 (0.0-1.0)
                'level': 0.5,         # 输出电平 (0.0-1.0)
                'bias': 0.0,          # 偏置 (-1.0-1.0)
                'type': 'overdrive',  # 类型: overdrive, distortion, fuzz, clipper
                'pre_filter': 1000.0, # 预滤波器频率 (Hz)
                'post_filter': 5000.0, # 后滤波器频率 (Hz)
                'rectification': 'full', # 整流: full, half, none
                'asymmetry': 0.0,     # 不对称度 (0.0-1.0)
                'mix': 1.0            # 湿信号混合 (0.0-1.0)
            }
            
            # 合并参数
            effect_params = default_params.copy()
            effect_params.update(parameters)
            
            # 创建效果对象
            effect = {
                'id': effect_id,
                'type': 'distortion',
                'parameters': effect_params,
                'active': True,
                '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']
        buffers = {}
        
        # 输入和输出缓冲区
        buffers['input'] = np.zeros(self.buffer_size)
        buffers['output'] = np.zeros(self.buffer_size)
        
        # 滤波器状态缓冲区
        buffers['pre_filter_state'] = np.zeros(2)  # 双通道滤波器状态
        buffers['post_filter_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:
            处理后的音频数据
        """
        # 获取参数
        drive = max(0.0, min(1.0, parameters.get('drive', 0.5)))
        tone = max(0.0, min(1.0, parameters.get('tone', 0.5)))
        level = max(0.0, min(1.0, parameters.get('level', 0.5)))
        bias = max(-1.0, min(1.0, parameters.get('bias', 0.0)))
        distortion_type = parameters.get('type', 'overdrive')
        pre_filter = max(100.0, min(10000.0, parameters.get('pre_filter', 1000.0)))
        post_filter = max(1000.0, min(20000.0, parameters.get('post_filter', 5000.0)))
        rectification = parameters.get('rectification', 'full')
        asymmetry = max(0.0, min(1.0, parameters.get('asymmetry', 0.0)))
        mix = max(0.0, min(1.0, parameters.get('mix', 1.0)))
        
        # 创建输出数组
        if audio_data.ndim == 1:
            # 单声道处理
            output_data = np.zeros_like(audio_data)
            
            for i in range(len(audio_data)):
                sample = audio_data[i]
                
                # 应用偏置
                biased_sample = sample + bias
                
                # 预滤波
                filtered_sample = self._apply_pre_filter(biased_sample, pre_filter)
                
                # 应用失真
                distorted_sample = self._apply_distortion(
                    filtered_sample, drive, distortion_type, rectification, asymmetry)
                
                # 后滤波
                filtered_distorted = self._apply_post_filter(distorted_sample, post_filter, tone)
                
                # 应用输出电平
                leveled_sample = filtered_distorted * level
                
                # 混合干湿信号
                output_data[i] = sample * (1.0 - mix) + leveled_sample * mix
                
        else:
            # 多声道处理
            output_data = np.zeros_like(audio_data)
            
            for channel in range(audio_data.shape[0]):
                for i in range(audio_data.shape[1]):
                    sample = audio_data[channel, i]
                    
                    # 应用偏置
                    biased_sample = sample + bias
                    
                    # 预滤波
                    filtered_sample = self._apply_pre_filter(biased_sample, pre_filter)
                    
                    # 应用失真
                    distorted_sample = self._apply_distortion(
                        filtered_sample, drive, distortion_type, rectification, asymmetry)
                    
                    # 后滤波
                    filtered_distorted = self._apply_post_filter(distorted_sample, post_filter, tone)
                    
                    # 应用输出电平
                    leveled_sample = filtered_distorted * level
                    
                    # 混合干湿信号
                    output_data[channel, i] = sample * (1.0 - mix) + leveled_sample * mix
                    
        # 确保输出在有效范围内
        processed_data = np.clip(output_data, -1.0, 1.0)
        return processed_data
        
    def _apply_pre_filter(self, sample: float, cutoff: float) -> float:
        """
        应用预滤波器
        
        Args:
            sample: 输入样本
            cutoff: 截止频率 (Hz)
            
        Returns:
            滤波后的样本
        """
        # 简化的低通滤波器
        # 实际应用中会使用更复杂的滤波器设计
        
        # 计算滤波系数
        rc = 1.0 / (2.0 * math.pi * cutoff)
        dt = 1.0 / self.sample_rate
        alpha = dt / (rc + dt)
        
        # 简单的一阶低通滤波
        filtered = alpha * sample + (1.0 - alpha) * sample  # 简化实现
        return filtered
        
    def _apply_distortion(self, sample: float, drive: float, 
                         distortion_type: str, rectification: str, asymmetry: float) -> float:
        """
        应用失真效果
        
        Args:
            sample: 输入样本
            drive: 驱动强度
            distortion_type: 失真类型
            rectification: 整流类型
            asymmetry: 不对称度
            
        Returns:
            失真后的样本
        """
        # 应用驱动
        driven_sample = sample * (1.0 + drive * 10.0)
        
        # 根据类型应用失真
        if distortion_type == 'overdrive':
            distorted = self._soft_clip(driven_sample)
        elif distortion_type == 'distortion':
            distorted = self._hard_clip(driven_sample)
        elif distortion_type == 'fuzz':
            distorted = self._fuzz_distort(driven_sample)
        elif distortion_type == 'clipper':
            distorted = self._asymmetric_clip(driven_sample, asymmetry)
        else:
            distorted = self._soft_clip(driven_sample)
            
        # 应用整流
        if rectification == 'full':
            rectified = abs(distorted)
        elif rectification == 'half':
            rectified = max(0.0, distorted)
        else:
            rectified = distorted
            
        return rectified
        
    def _soft_clip(self, sample: float) -> float:
        """
        软削波
        
        Args:
            sample: 输入样本
            
        Returns:
            削波后的样本
        """
        # 双曲正切软削波
        return math.tanh(sample)
        
    def _hard_clip(self, sample: float) -> float:
        """
        硬削波
        
        Args:
            sample: 输入样本
            
        Returns:
            削波后的样本
        """
        # 简单的硬削波
        return max(-1.0, min(1.0, sample))
        
    def _fuzz_distort(self, sample: float) -> float:
        """
        模糊失真
        
        Args:
            sample: 输入样本
            
        Returns:
            失真后的样本
        """
        # 强烈的非线性失真
        amplified = sample * 10.0
        if amplified > 0:
            fuzzed = 1.0 - math.exp(-amplified)
        else:
            fuzzed = -1.0 + math.exp(amplified)
        return fuzzed
        
    def _asymmetric_clip(self, sample: float, asymmetry: float) -> float:
        """
        不对称削波
        
        Args:
            sample: 输入样本
            asymmetry: 不对称度
            
        Returns:
            削波后的样本
        """
        positive_limit = 1.0
        negative_limit = -1.0 + asymmetry * 0.5
        
        if sample > positive_limit:
            return positive_limit
        elif sample < negative_limit:
            return negative_limit
        else:
            return sample
            
    def _apply_post_filter(self, sample: float, cutoff: float, tone: float) -> float:
        """
        应用后滤波器
        
        Args:
            sample: 输入样本
            cutoff: 截止频率 (Hz)
            tone: 音调控制
            
        Returns:
            滤波后的样本
        """
        # 结合音调控制的滤波器
        adjusted_cutoff = cutoff * (0.5 + tone * 0.5)
        
        # 简化的滤波器
        rc = 1.0 / (2.0 * math.pi * adjusted_cutoff)
        dt = 1.0 / self.sample_rate
        alpha = dt / (rc + dt)
        
        # 简单的一阶滤波
        filtered = alpha * sample + (1.0 - alpha) * sample  # 简化实现
        return filtered
        
    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_drive(self, effect_id: str, drive: float) -> bool:
        """
        设置驱动强度
        
        Args:
            effect_id: 效果ID
            drive: 驱动强度 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'drive', max(0.0, min(1.0, drive)))
        
    def set_tone(self, effect_id: str, tone: float) -> bool:
        """
        设置音调
        
        Args:
            effect_id: 效果ID
            tone: 音调 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'tone', max(0.0, min(1.0, tone)))
        
    def set_level(self, effect_id: str, level: float) -> bool:
        """
        设置输出电平
        
        Args:
            effect_id: 效果ID
            level: 输出电平 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'level', max(0.0, min(1.0, level)))
        
    def set_bias(self, effect_id: str, bias: float) -> bool:
        """
        设置偏置
        
        Args:
            effect_id: 效果ID
            bias: 偏置 (-1.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'bias', max(-1.0, min(1.0, bias)))
        
    def set_type(self, effect_id: str, distortion_type: str) -> bool:
        """
        设置失真类型
        
        Args:
            effect_id: 效果ID
            distortion_type: 失真类型 (overdrive, distortion, fuzz, clipper)
            
        Returns:
            是否设置成功
        """
        valid_types = ['overdrive', 'distortion', 'fuzz', 'clipper']
        if distortion_type not in valid_types:
            print(f"✗ 无效的失真类型: {distortion_type}")
            return False
            
        return self.set_parameter(effect_id, 'type', distortion_type)
        
    def set_pre_filter(self, effect_id: str, frequency: float) -> bool:
        """
        设置预滤波器频率
        
        Args:
            effect_id: 效果ID
            frequency: 频率 (Hz)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'pre_filter', max(100.0, min(10000.0, frequency)))
        
    def set_post_filter(self, effect_id: str, frequency: float) -> bool:
        """
        设置后滤波器频率
        
        Args:
            effect_id: 效果ID
            frequency: 频率 (Hz)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'post_filter', max(1000.0, min(20000.0, frequency)))
        
    def set_rectification(self, effect_id: str, rectification: str) -> bool:
        """
        设置整流类型
        
        Args:
            effect_id: 效果ID
            rectification: 整流类型 (full, half, none)
            
        Returns:
            是否设置成功
        """
        valid_rectifications = ['full', 'half', 'none']
        if rectification not in valid_rectifications:
            print(f"✗ 无效的整流类型: {rectification}")
            return False
            
        return self.set_parameter(effect_id, 'rectification', rectification)
        
    def set_asymmetry(self, effect_id: str, asymmetry: float) -> bool:
        """
        设置不对称度
        
        Args:
            effect_id: 效果ID
            asymmetry: 不对称度 (0.0-1.0)
            
        Returns:
            是否设置成功
        """
        return self.set_parameter(effect_id, 'asymmetry', max(0.0, min(1.0, asymmetry)))
        
    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 create_preset(self, preset_name: str) -> Dict[str, Any]:
        """
        创建失真效果预设
        
        Args:
            preset_name: 预设名称
            
        Returns:
            预设参数字典
        """
        presets = {
            'mild_overdrive': {
                'drive': 0.3,
                'tone': 0.7,
                'level': 0.6,
                'type': 'overdrive',
                'pre_filter': 2000.0,
                'post_filter': 6000.0,
                'rectification': 'none',
                'mix': 1.0
            },
            'heavy_overdrive': {
                'drive': 0.7,
                'tone': 0.5,
                'level': 0.8,
                'type': 'overdrive',
                'pre_filter': 1000.0,
                'post_filter': 4000.0,
                'rectification': 'none',
                'mix': 1.0
            },
            'classic_distortion': {
                'drive': 0.8,
                'tone': 0.6,
                'level': 0.7,
                'type': 'distortion',
                'pre_filter': 800.0,
                'post_filter': 3000.0,
                'rectification': 'none',
                'mix': 1.0
            },
            'metal_distortion': {
                'drive': 1.0,
                'tone': 0.4,
                'level': 0.9,
                'type': 'distortion',
                'pre_filter': 500.0,
                'post_filter': 2000.0,
                'rectification': 'none',
                'mix': 1.0
            },
            'fuzz_box': {
                'drive': 0.9,
                'tone': 0.3,
                'level': 0.8,
                'type': 'fuzz',
                'pre_filter': 300.0,
                'post_filter': 1500.0,
                'rectification': 'full',
                'mix': 1.0
            },
            'bass_overdrive': {
                'drive': 0.4,
                'tone': 0.8,
                'level': 0.7,
                'type': 'overdrive',
                'pre_filter': 3000.0,
                'post_filter': 8000.0,
                'rectification': 'none',
                'mix': 1.0
            },
            'tube_amp': {
                'drive': 0.6,
                'tone': 0.7,
                'level': 0.75,
                'type': 'overdrive',
                'pre_filter': 1500.0,
                'post_filter': 5000.0,
                'rectification': 'none',
                'asymmetry': 0.3,
                'mix': 1.0
            },
            'bit_crusher': {
                'drive': 0.5,
                'tone': 0.4,
                'level': 0.6,
                'type': 'distortion',
                'pre_filter': 4000.0,
                'post_filter': 10000.0,
                'rectification': 'none',
                'mix': 1.0
            }
        }
        
        return presets.get(preset_name, {}).copy()
        
    def get_drive_meter(self, effect_id: str) -> float:
        """
        获取驱动表
        
        Args:
            effect_id: 效果ID
            
        Returns:
            当前驱动值 (0.0-1.0)
        """
        if effect_id not in self.effects:
            return 0.0
            
        return self.effects[effect_id]['parameters'].get('drive', 0.0)
        
    def get_tone_meter(self, effect_id: str) -> float:
        """
        获取音调表
        
        Args:
            effect_id: 效果ID
            
        Returns:
            当前音调值 (0.0-1.0)
        """
        if effect_id not in self.effects:
            return 0.0
            
        return self.effects[effect_id]['parameters'].get('tone', 0.0)

