"""
处理各类音频数据与bytes的转换
"""

import wave
from pydub import AudioSegment
import io


def wav_to_bytes(wav_path: str) -> bytes:
    """
    将WAV文件读取为bytes数据。

    参数:
        wav_path (str): WAV文件的路径。

    返回:
        bytes: WAV文件的原始字节数据。

    异常:
        FileNotFoundError: 如果WAV文件不存在。
        wave.Error: 如果文件不是有效的WAV文件。
    """
    try:
        with wave.open(wav_path, "rb") as wf:
            # 读取所有帧
            frames = wf.readframes(wf.getnframes())
            return frames
    except FileNotFoundError:
        # 可以选择记录日志或重新抛出，这里为了清晰直接重新抛出
        raise FileNotFoundError(f"错误: 未找到WAV文件 '{wav_path}'")
    except wave.Error as e:
        raise wave.Error(f"错误: 打开或读取WAV文件 '{wav_path}' 失败 - {e}")


def bytes_to_wav(
    bytes_data: bytes, wav_path: str, nchannels: int, sampwidth: int, framerate: int
):
    """
    将bytes数据写入为WAV文件。

    参数:
        bytes_data (bytes): 音频的字节数据。
        wav_path (str): 保存WAV文件的路径。
        nchannels (int): 声道数 (例如 1 for mono, 2 for stereo)。
        sampwidth (int): 采样宽度 (字节数, 例如 2 for 16-bit audio)。
        framerate (int): 采样率 (例如 44100, 16000)。

    异常:
        wave.Error: 如果写入WAV文件失败。
    """
    try:
        with wave.open(wav_path, "wb") as wf:
            wf.setnchannels(nchannels)
            wf.setsampwidth(sampwidth)
            wf.setframerate(framerate)
            wf.writeframes(bytes_data)
    except wave.Error as e:
        raise wave.Error(f"错误: 写入WAV文件 '{wav_path}' 失败 - {e}")
    except Exception as e:
        # 捕获其他可能的写入错误
        raise Exception(f"写入WAV文件 '{wav_path}' 时发生未知错误 - {e}")


def mp3_to_bytes(mp3_path: str) -> bytes:
    """
    将MP3文件转换为bytes数据 (原始PCM数据)。

    参数:
        mp3_path (str): MP3文件的路径。

    返回:
        bytes: MP3文件解码后的原始PCM字节数据。

    异常:
        FileNotFoundError: 如果MP3文件不存在。
        pydub.exceptions.CouldntDecodeError: 如果MP3文件无法解码。
    """
    try:
        audio = AudioSegment.from_mp3(mp3_path)
        # 获取原始PCM数据
        return audio.raw_data
    except FileNotFoundError:
        raise FileNotFoundError(f"错误: 未找到MP3文件 '{mp3_path}'")
    except Exception as e:  # pydub 可能抛出多种解码相关的错误
        raise Exception(f"错误: 处理MP3文件 '{mp3_path}' 失败 - {e}")


def bytes_to_mp3(
    bytes_data: bytes,
    mp3_path: str,
    frame_rate: int,
    channels: int,
    sample_width: int,
    bitrate: str = "192k",
):
    """
    将原始PCM bytes数据转换为MP3文件。

    参数:
        bytes_data (bytes): 原始PCM字节数据。
        mp3_path (str): 保存MP3文件的路径。
        frame_rate (int): 原始PCM数据的采样率 (例如 44100)。
        channels (int): 原始PCM数据的声道数 (例如 1 for mono, 2 for stereo)。
        sample_width (int): 原始PCM数据的采样宽度 (字节数, 例如 2 for 16-bit)。
        bitrate (str): MP3编码的比特率 (例如 "128k", "192k", "320k")。

    异常:
        Exception: 如果转换或写入MP3文件失败。
    """
    try:
        # 从原始数据创建AudioSegment对象
        audio = AudioSegment(
            data=bytes_data,
            sample_width=sample_width,
            frame_rate=frame_rate,
            channels=channels,
        )
        # 导出为MP3
        audio.export(mp3_path, format="mp3", bitrate=bitrate)
    except Exception as e:
        raise Exception(f"错误: 转换或写入MP3文件 '{mp3_path}' 失败 - {e}")
