use crate::config::Config;
use crate::store::Store;
use anyhow::{Context, Result};
use chrono::NaiveDate;
use colored::Colorize;

pub fn run(config: &Config, ref_path: &str, date: NaiveDate) -> Result<()> {
    let store = Store::new(&config.storage_dir);

    let original_body = store
        .extract_element_body(ref_path, date)?
        .with_context(|| format!("element '{}' not found", ref_path))?;

    // Write to a named temp file so $EDITOR shows a meaningful filename.
    let tmp_path = std::env::temp_dir().join(format!("mps-edit-{}.txt", std::process::id()));
    std::fs::write(&tmp_path, &original_body)?;

    let editor = std::env::var("EDITOR")
        .or_else(|_| std::env::var("VISUAL"))
        .unwrap_or_else(|_| "vim".to_string());

    let status = std::process::Command::new(&editor)
        .arg(&tmp_path)
        .status()
        .with_context(|| format!("failed to launch editor '{}'", editor))?;

    if !status.success() {
        let _ = std::fs::remove_file(&tmp_path);
        anyhow::bail!("editor exited with non-zero status");
    }

    let new_body = std::fs::read_to_string(&tmp_path)?;
    let _ = std::fs::remove_file(&tmp_path);

    let new_body = new_body.trim_matches('\n');
    if new_body == original_body.trim_matches('\n') {
        println!("  {} (no changes)", "unchanged".dimmed());
        return Ok(());
    }

    let changed = store
        .replace_element_body(ref_path, new_body, date)
        .with_context(|| format!("failed to write element '{}'", ref_path))?;

    if changed {
        println!("  {} {}", "updated:".green(), ref_path);
    } else {
        println!(
            "  {} element '{}' could not be updated",
            "warn:".yellow(),
            ref_path
        );
    }

    Ok(())
}
