// Transkripsjons-dispatcher — delegerer til synops-transcribe CLI.
//
// Maskinrommet orkestrerer, CLI-verktøyet gjør jobben.
// Ref: docs/retninger/unix_filosofi.md

use crate::cas::CasStore;
use crate::jobs::JobRow;
use std::process::Stdio;
use uuid::Uuid;

/// Synops-transcribe binary path.
/// Søker i PATH, men kan overrides med SYNOPS_TRANSCRIBE_BIN.
fn transcribe_bin() -> String {
    std::env::var("SYNOPS_TRANSCRIBE_BIN")
        .unwrap_or_else(|_| "synops-transcribe".to_string())
}

/// Handler for whisper_transcribe-jobber.
///
/// Spawner synops-transcribe med --write for å gjøre alt arbeidet:
/// Whisper-kall, SRT-parsing, DB-skriving, ressurslogging.
///
/// Payload forventer:
///   - media_node_id: UUID — noden som skal oppdateres
///   - cas_hash: String — CAS-nøkkel til lydfilen
///   - mime: String — MIME-type (brukes for filnavn-hint)
///   - language: String (valgfritt, default "no")
///   - initial_prompt: String (valgfritt — navneliste for bedre egennavn)
///   - requested_by: UUID (valgfritt — brukeren som utløste jobben)
pub async fn handle_whisper_job(
    job: &JobRow,
    cas: &CasStore,
    whisper_url: &str,
) -> Result<serde_json::Value, String> {
    let media_node_id: Uuid = job.payload["media_node_id"]
        .as_str()
        .ok_or("Mangler media_node_id i payload")?
        .parse()
        .map_err(|e| format!("Ugyldig media_node_id: {e}"))?;

    let cas_hash = job.payload["cas_hash"]
        .as_str()
        .ok_or("Mangler cas_hash i payload")?;

    let mime = job.payload["mime"]
        .as_str()
        .unwrap_or("audio/mpeg");

    let language = job.payload["language"]
        .as_str()
        .unwrap_or("no");

    let model = std::env::var("WHISPER_MODEL")
        .unwrap_or_else(|_| "medium".to_string());

    // Hent initial_prompt: payload > miljøvariabel > ingen
    let initial_prompt = match job.payload["initial_prompt"].as_str() {
        Some(p) => Some(p.to_string()),
        None => std::env::var("WHISPER_INITIAL_PROMPT").ok(),
    };

    // Bygg kommando
    let bin = transcribe_bin();
    let mut cmd = tokio::process::Command::new(&bin);

    cmd.arg("--cas-hash").arg(cas_hash)
        .arg("--model").arg(&model)
        .arg("--language").arg(language)
        .arg("--mime").arg(mime)
        .arg("--node-id").arg(media_node_id.to_string())
        .arg("--write");

    if let Some(ref prompt) = initial_prompt {
        cmd.arg("--initial-prompt").arg(prompt);
    }

    if let Some(requested_by) = job.payload["requested_by"].as_str() {
        cmd.arg("--requested-by").arg(requested_by);
    }

    // Sett miljøvariabler CLI-verktøyet trenger
    let db_url = std::env::var("DATABASE_URL")
        .map_err(|_| "DATABASE_URL ikke satt".to_string())?;
    let cas_root = cas.root().to_string_lossy().to_string();

    cmd.env("DATABASE_URL", &db_url)
        .env("CAS_ROOT", &cas_root)
        .env("WHISPER_URL", whisper_url);

    cmd.stdout(Stdio::piped())
        .stderr(Stdio::piped());

    tracing::info!(
        media_node_id = %media_node_id,
        cas_hash = %cas_hash,
        model = %model,
        bin = %bin,
        "Starter synops-transcribe"
    );

    // Spawn og vent
    let child = cmd.spawn().map_err(|e| format!("Kunne ikke starte {bin}: {e}"))?;
    let output = child
        .wait_with_output()
        .await
        .map_err(|e| format!("Feil ved kjøring av {bin}: {e}"))?;

    let stderr = String::from_utf8_lossy(&output.stderr);
    if !stderr.is_empty() {
        tracing::info!(stderr = %stderr, "synops-transcribe stderr");
    }

    if !output.status.success() {
        let code = output.status.code().unwrap_or(-1);
        return Err(format!(
            "synops-transcribe feilet (exit {code}): {stderr}"
        ));
    }

    // Parse stdout som JSON — det er resultatet
    let stdout = String::from_utf8_lossy(&output.stdout);
    let result: serde_json::Value = serde_json::from_str(&stdout)
        .map_err(|e| format!("Kunne ikke parse synops-transcribe output: {e}"))?;

    tracing::info!(
        media_node_id = %media_node_id,
        segments = result["segment_count"].as_u64().unwrap_or(0),
        "synops-transcribe fullført"
    );

    Ok(result)
}
