from pathlib import Path
import shutil
import subprocess
import tempfile

try:
    import imageio_ffmpeg
except ImportError:
    imageio_ffmpeg = None


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


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 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 configure_ffmpeg():
    if imageio_ffmpeg is None:
        raise RuntimeError(
            "ffmpeg belum tersedia. Jalankan `pip install imageio-ffmpeg` "
            "di virtual environment backend."
        )
    try:
        return imageio_ffmpeg.get_ffmpeg_exe()
    except Exception as error:
        raise RuntimeError(
            "ffmpeg belum tersedia. Jalankan `pip install imageio-ffmpeg` "
            "atau install ffmpeg di sistem operasi."
        ) from error


def convert_audio_to_wav(input_path, output_path=None):
    input_path = Path(input_path)
    validate_audio_extension(input_path)

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

    if input_path.suffix.lower() == ".wav" and output_path is None:
        return input_path

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

    if input_path.suffix.lower() == ".wav":
        if input_path.resolve() != output_path.resolve():
            shutil.copyfile(input_path, output_path)
        return output_path

    command = [
        configure_ffmpeg(),
        "-y",
        "-i",
        str(input_path),
        "-vn",
        "-ac",
        "1",
        "-ar",
        str(TARGET_SAMPLE_RATE),
        "-f",
        "wav",
        str(output_path),
    ]

    try:
        result = subprocess.run(command, capture_output=True, text=True, check=False)
    except FileNotFoundError as error:
        raise RuntimeError(
            "ffmpeg tidak bisa dijalankan. Pastikan dependency `imageio-ffmpeg` "
            "sudah terpasang di virtual environment backend."
        ) from error

    if result.returncode != 0:
        error_message = result.stderr.strip() or "Tidak ada detail error dari ffmpeg."
        raise RuntimeError(f"Konversi audio gagal: {error_message}")

    if not output_path.exists():
        raise RuntimeError("Konversi audio gagal: file WAV output tidak terbentuk.")

    return output_path


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