"""
Audio format conversion utilities.

Twilio uses mulaw 8kHz, while our internal format is PCM16 24kHz.
"""

try:
    import audioop
except ImportError:
    import audioop_lts as audioop
import wave

SAMPLE_RATE = 24000
SAMPLE_WIDTH = 2  # 16-bit
CHANNELS = 1


def pcm16_24k_to_mulaw_8k(pcm_audio: bytes) -> bytes:
    """
    Convert PCM16 24kHz to mulaw 8kHz for Twilio.

    Args:
        pcm_audio: PCM16 audio at 24kHz

    Returns:
        mulaw audio at 8kHz
    """
    if not pcm_audio:
        return b""

    # Downsample 24kHz -> 8kHz
    downsampled, _ = audioop.ratecv(pcm_audio, 2, 1, 24000, 8000, None)

    # Convert to mulaw
    mulaw = audioop.lin2ulaw(downsampled, 2)

    return mulaw


def mulaw_8k_to_pcm16_24k(mulaw_audio: bytes) -> bytes:
    """
    Convert mulaw 8kHz from Twilio to PCM16 24kHz.

    Args:
        mulaw_audio: mulaw audio at 8kHz

    Returns:
        PCM16 audio at 24kHz
    """
    if not mulaw_audio:
        return b""

    # Convert mulaw -> linear PCM
    pcm = audioop.ulaw2lin(mulaw_audio, 2)

    # Upsample 8kHz -> 24kHz
    upsampled, _ = audioop.ratecv(pcm, 2, 1, 8000, 24000, None)

    return upsampled


def mulaw_8k_to_pcm16_8k(mulaw_audio: bytes) -> bytes:
    """Convert mulaw 8kHz to PCM16 8kHz (no resampling)."""
    if not mulaw_audio:
        return b""

    return audioop.ulaw2lin(mulaw_audio, 2)


def pcm16_to_mulaw(pcm_audio: bytes) -> bytes:
    """Convert PCM16 to mulaw (same sample rate)."""
    if not pcm_audio:
        return b""

    return audioop.lin2ulaw(pcm_audio, 2)


def save_audio(audio: bytes, filename: str, sample_rate: int = SAMPLE_RATE, channels: int = CHANNELS) -> None:
    """Save PCM16 audio to WAV file.

    Args:
        audio: PCM16 audio bytes
        filename: Output file path
        sample_rate: Sample rate (default 24kHz)
        channels: Number of channels (1=mono, 2=stereo)
    """
    with wave.open(filename, "wb") as wav:
        wav.setnchannels(channels)
        wav.setsampwidth(SAMPLE_WIDTH)
        wav.setframerate(sample_rate)
        wav.writeframes(audio)
