use std::process::Command;
use std::io::Write;
use aurora_core::{AuroraResult, AuroraError};

pub enum AudioBackend {
    Ffplay,
    Mpg123,
    Mpv,
    Aplay,
    Paplay,
    Sox,
}

const BACKENDS: &[(&str, &[&str])] = &[
    ("ffplay", &["-nodisp", "-autoexit", "-"]),
    ("mpg123", &["-q", "-"]),
    ("mpv", &["--no-video", "--cache=no", "-"]),
    ("aplay", &["-q"]),
    ("paplay", &[]),
    ("play", &["-q"]), // sox
];

pub fn find_audio_player() -> Option<(&'static str, &'static [&'static str])> {
    for (cmd, args) in BACKENDS {
        if Command::new(cmd).arg("--version").stdout(std::process::Stdio::null()).stderr(std::process::Stdio::null()).status().is_ok() {
            return Some((cmd, args));
        }
    }
    None
}

pub fn play_audio(data: &[u8]) -> AuroraResult<()> {
    let (player, args) = find_audio_player()
        .ok_or_else(|| AuroraError::TtsError(
            "No audio player found. Install ffplay, mpg123, mpv, aplay, paplay, or sox.".to_string()
        ))?;

    let mut child = Command::new(player)
        .args(args)
        .stdin(std::process::Stdio::piped())
        .stdout(std::process::Stdio::null())
        .stderr(std::process::Stdio::null())
        .spawn()
        .map_err(|e| AuroraError::TtsError(format!("Failed to launch {player}: {e}")))?;

    if let Some(ref mut stdin) = child.stdin {
        stdin.write_all(data)
            .map_err(|e| AuroraError::TtsError(format!("Failed to pipe audio: {e}")))?;
    }

    child.wait()
        .map_err(|e| AuroraError::TtsError(format!("Audio playback failed: {e}")))?;

    Ok(())
}
