use axum::response::Json;
use std::sync::Mutex;

use crate::audio;

static CMD_QUEUE: Mutex<Vec<(String, Option<String>)>> = Mutex::new(Vec::new());

pub async fn post_command(
    Json(body): Json<serde_json::Value>,
) -> impl axum::response::IntoResponse {
    let cmd = body["cmd"].as_str().unwrap_or("").to_string();
    let val = body["val"].as_str().map(|s| s.to_string());
    let out = body["out"].as_str().map(|s| s.to_string());

    if cmd == "test_voice" {
        let lang = val.as_deref().unwrap_or("zh_TW");
        let voice_name = audio::voice_for_lang(lang);
        let phrase = audio::phrase_for_lang(lang);
        if let Some(d) = out.as_deref() {
            if !d.is_empty() {
                std::process::Command::new("SwitchAudioSource")
                    .args(["-t", "output", "-s", d])
                    .output()
                    .ok();
            }
        }
        std::process::Command::new("say")
            .args(["-v", &voice_name, &phrase])
            .spawn()
            .ok();
    } else if cmd == "vol_up" {
        std::process::Command::new("osascript")
            .args([
                "-e",
                "set volume output volume (output volume of (get volume settings)) + 10",
            ])
            .output()
            .ok();
    } else if cmd == "vol_down" {
        std::process::Command::new("osascript")
            .args([
                "-e",
                "set volume output volume (output volume of (get volume settings)) - 10",
            ])
            .output()
            .ok();
    } else {
        CMD_QUEUE.lock().unwrap().push((cmd, val));
    }

    Json(serde_json::json!({"ok": true}))
}

pub async fn get_commands() -> Json<serde_json::Value> {
    let mut queue = CMD_QUEUE.lock().unwrap();
    let cmds: Vec<_> = queue
        .drain(..)
        .map(|(c, v)| serde_json::json!({"cmd": c, "val": v}))
        .collect();
    Json(serde_json::json!(cmds))
}
