"""
音频工具类
提供音频处理相关的实用工具函数
"""

import math
from typing import Tuple, List, Dict, Any
from panda3d.core import Vec3

def calculate_distance(pos1: Tuple[float, float, float], 
                      pos2: Tuple[float, float, float]) -> float:
    """
    计算两点间距离
    
    Args:
        pos1: 第一个点 (x, y, z)
        pos2: 第二个点 (x, y, z)
        
    Returns:
        距离
    """
    dx = pos1[0] - pos2[0]
    dy = pos1[1] - pos2[1]
    dz = pos1[2] - pos2[2]
    return math.sqrt(dx*dx + dy*dy + dz*dz)


def calculate_volume_attenuation(distance: float, max_distance: float = 50.0, 
                               min_volume: float = 0.0, max_volume: float = 1.0) -> float:
    """
    计算基于距离的音量衰减
    
    Args:
        distance: 距离
        max_distance: 最大距离（在此距离外音量为最小值）
        min_volume: 最小音量
        max_volume: 最大音量
        
    Returns:
        计算后的音量
    """
    if distance >= max_distance:
        return min_volume
        
    # 线性衰减
    attenuation = 1.0 - (distance / max_distance)
    volume = min_volume + (max_volume - min_volume) * attenuation
    return max(min_volume, min(max_volume, volume))


def calculate_pan(position: Tuple[float, float, float], 
                 listener_position: Tuple[float, float, float]) -> float:
    """
    计算立体声平移（左/右声道平衡）
    
    Args:
        position: 音源位置
        listener_position: 听者位置
        
    Returns:
        平移值 (-1.0 到 1.0，-1为左，1为右)
    """
    # 计算相对位置
    rel_x = position[0] - listener_position[0]
    rel_z = position[2] - listener_position[2]
    
    # 计算角度
    angle = math.atan2(rel_x, rel_z)
    
    # 转换为平移值
    pan = math.sin(angle)
    return max(-1.0, min(1.0, pan))


def interpolate_positions(start_pos: Tuple[float, float, float], 
                         end_pos: Tuple[float, float, float], 
                         steps: int) -> List[Tuple[float, float, float]]:
    """
    在两点间插值生成位置列表
    
    Args:
        start_pos: 起始位置
        end_pos: 结束位置
        steps: 插值步数
        
    Returns:
        插值位置列表
    """
    if steps <= 1:
        return [start_pos, end_pos]
        
    positions = []
    for i in range(steps):
        t = i / (steps - 1)
        x = start_pos[0] + (end_pos[0] - start_pos[0]) * t
        y = start_pos[1] + (end_pos[1] - start_pos[1]) * t
        z = start_pos[2] + (end_pos[2] - start_pos[2]) * t
        positions.append((x, y, z))
        
    return positions


def validate_audio_file(filepath: str) -> Dict[str, Any]:
    """
    验证音频文件
    
    Args:
        filepath: 音频文件路径
        
    Returns:
        验证结果字典
    """
    import os
    
    result = {
        'valid': False,
        'exists': False,
        'file_size': 0,
        'extension': '',
        'supported': False
    }
    
    # 检查文件是否存在
    if not os.path.exists(filepath):
        result['error'] = '文件不存在'
        return result
        
    result['exists'] = True
    
    # 获取文件信息
    result['file_size'] = os.path.getsize(filepath)
    _, extension = os.path.splitext(filepath)
    result['extension'] = extension.lower()
    
    # 检查是否为支持的格式
    supported_formats = ['.wav', '.ogg', '.mp3']
    result['supported'] = result['extension'] in supported_formats
    
    # 验证通过
    if result['supported'] and result['file_size'] > 0:
        result['valid'] = True
        
    return result


def generate_test_tone(frequency: float = 440.0, duration: float = 1.0, 
                      sample_rate: int = 44100) -> bytes:
    """
    生成测试音调（正弦波）
    
    Args:
        frequency: 频率 (Hz)
        duration: 持续时间 (秒)
        sample_rate: 采样率
        
    Returns:
        音频数据字节
    """
    import math
    import struct
    
    # 生成正弦波数据
    num_samples = int(duration * sample_rate)
    audio_data = bytearray()
    
    for i in range(num_samples):
        # 生成正弦波样本
        t = i / sample_rate
        sample = math.sin(2 * math.pi * frequency * t)
        
        # 转换为16位整数
        sample_int = int(sample * 32767)
        audio_data.extend(struct.pack('<h', sample_int))
        
    return bytes(audio_data)


def convert_to_mono(audio_data: bytes, channels: int = 2) -> bytes:
    """
    将多声道音频转换为单声道
    
    Args:
        audio_data: 音频数据
        channels: 声道数
        
    Returns:
        单声道音频数据
    """
    if channels == 1:
        return audio_data
        
    # 假设16位音频数据
    sample_size = 2
    frame_size = sample_size * channels
    
    mono_data = bytearray()
    for i in range(0, len(audio_data), frame_size):
        # 取第一个声道的数据
        mono_data.extend(audio_data[i:i+sample_size])
        
    return bytes(mono_data)


def apply_volume_multiplier(audio_data: bytes, volume: float) -> bytes:
    """
    应用音量乘数到音频数据
    
    Args:
        audio_data: 音频数据
        volume: 音量乘数 (0.0-1.0)
        
    Returns:
        处理后的音频数据
    """
    import struct
    
    if volume == 1.0:
        return audio_data
        
    # 假设16位音频数据
    sample_count = len(audio_data) // 2
    processed_data = bytearray()
    
    for i in range(sample_count):
        # 解包16位样本
        sample = struct.unpack_from('<h', audio_data, i * 2)[0]
        
        # 应用音量
        sample = int(sample * volume)
        
        # 限制范围
        sample = max(-32768, min(32767, sample))
        
        # 重新打包
        processed_data.extend(struct.pack('<h', sample))
        
    return bytes(processed_data)


def calculate_doppler_shift(source_velocity: Tuple[float, float, float], 
                          listener_velocity: Tuple[float, float, float],
                          sound_speed: float = 343.0) -> float:
    """
    计算多普勒频移
    
    Args:
        source_velocity: 音源速度向量
        listener_velocity: 听者速度向量
        sound_speed: 声速 (米/秒)
        
    Returns:
        频率比率 (播放频率/原始频率)
    """
    # 计算相对速度
    rel_velocity_x = source_velocity[0] - listener_velocity[0]
    rel_velocity_z = source_velocity[2] - listener_velocity[2]
    
    # 计算速度大小
    source_speed = math.sqrt(rel_velocity_x**2 + rel_velocity_z**2)
    
    # 简化的多普勒效应计算
    if sound_speed > source_speed:
        ratio = (sound_speed - source_speed) / sound_speed
        return max(0.5, min(2.0, ratio))  # 限制在合理范围内
    else:
        return 0.5  # 音源速度接近或超过声速时的处理


def create_hrtf_filter(angle: float, elevation: float) -> Dict[str, List[float]]:
    """
    创建HRTF（头部相关传递函数）滤波器
    
    Args:
        angle: 水平角度 (度)
        elevation: 垂直角度 (度)
        
    Returns:
        左右声道滤波器系数
    """
    # 这是一个简化的HRTF实现
    # 实际应用中会使用真实的HRTF测量数据
    
    # 简单的左右声道延迟差异
    angle_rad = math.radians(angle)
    delay_diff = math.sin(angle_rad) * 0.001  # 最大1毫秒延迟差异
    
    # 简单的左右声道幅度差异
    left_amp = 1.0 - max(0, math.sin(angle_rad)) * 0.3
    right_amp = 1.0 - max(0, -math.sin(angle_rad)) * 0.3
    
    return {
        'left': [left_amp, 0.0, 0.0],
        'right': [right_amp, 0.0, delay_diff]
    }


def calculate_reverb_parameters(room_size: Tuple[float, float, float], 
                              absorption: float = 0.5) -> Dict[str, float]:
    """
    根据房间尺寸计算混响参数
    
    Args:
        room_size: 房间尺寸 (长, 宽, 高)
        absorption: 吸收系数 (0.0-1.0)
        
    Returns:
        混响参数字典
    """
    length, width, height = room_size
    
    # 计算房间体积
    volume = length * width * height
    
    # 计算表面积
    surface_area = 2 * (length*width + length*height + width*height)
    
    # 简化的混响时间计算（Sabine公式）
    reverb_time = 0.161 * volume / (surface_area * absorption)
    
    # 限制在合理范围内
    reverb_time = max(0.1, min(10.0, reverb_time))
    
    return {
        'reverb_time': reverb_time,
        'early_reflections': reverb_time * 0.1,
        'late_reverb': reverb_time * 0.9,
        'density': min(1.0, volume / 1000.0),
        'diffusion': 1.0 - absorption
    }