from pathlib import Path
import tempfile
import warnings

with warnings.catch_warnings():
    warnings.filterwarnings(
        "ignore",
        message="Couldn't find ffmpeg or avconv.*",
        category=RuntimeWarning,
    )
    from pydub import AudioSegment

try:
    import imageio_ffmpeg
except ImportError:
    imageio_ffmpeg = None


TARGET_SAMPLE_RATE = 22050
SUPPORTED_AUDIO_EXTENSIONS = {".wav", ".mp3", ".m4a", ".ogg", ".flac", ".webm", ".aac"}

if imageio_ffmpeg is not None:
    AudioSegment.converter = imageio_ffmpeg.get_ffmpeg_exe()


def validate_audio_extension(file_path):
    extension = Path(file_path).suffix.lower()
    if extension not in SUPPORTED_AUDIO_EXTENSIONS:
        allowed = ", ".join(sorted(SUPPORTED_AUDIO_EXTENSIONS)).upper().replace(".", "")
        raise ValueError(f"Format audio tidak didukung: {extension}. Format yang didukung: {allowed}")


def save_uploaded_file_to_temp(uploaded_file):
    """
    Menyimpan file upload Streamlit ke file sementara.
    File ini bukan dataset dan tidak disimpan ke ml/data.
    """
    suffix = Path(uploaded_file.name).suffix.lower() or ".wav"
    validate_audio_extension(f"audio{suffix}")

    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
    try:
        temp_file.write(uploaded_file.getvalue())
        return Path(temp_file.name)
    finally:
        temp_file.close()


def create_temp_wav_path():
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
    temp_path = Path(temp_file.name)
    temp_file.close()
    return temp_path


def convert_audio_to_wav(input_path, output_path=None):
    """
    Konversi audio upload ke WAV mono 22050 Hz menggunakan pydub/ffmpeg.
    """
    input_path = Path(input_path)
    validate_audio_extension(input_path)

    if not input_path.exists():
        raise FileNotFoundError(f"File audio tidak ditemukan: {input_path}")

    output_path = Path(output_path) if output_path else create_temp_wav_path()
    output_path.parent.mkdir(parents=True, exist_ok=True)

    try:
        audio = AudioSegment.from_file(input_path)
    except FileNotFoundError as error:
        raise RuntimeError(
            "ffmpeg tidak ditemukan. Pastikan ffmpeg sudah terpasang dan dapat diakses oleh pydub."
        ) from error
    except Exception as error:
        raise RuntimeError(f"Gagal membaca atau mengonversi audio: {error}") from error

    audio = audio.set_channels(1).set_frame_rate(TARGET_SAMPLE_RATE)
    audio.export(output_path, format="wav")
    return output_path


def cleanup_temp_files(*paths):
    for path in paths:
        if path:
            Path(path).unlink(missing_ok=True)
