use std::{
    io::{self},
    os::unix::process::CommandExt,
    path::PathBuf,
    process::Command,
};

use crossterm::terminal::disable_raw_mode;

use crate::{Dance, LaunchKind, LocItem};

impl Dance {
    pub fn execute(&mut self, li: LocItem) -> io::Result<()> {
        match li.lkind {
            LaunchKind::Edit => self.launch_edit(li.path)?,
            LaunchKind::Cd => self.launch_cd(li.path)?,
            LaunchKind::Open => self.launch_open(li.path)?,
        }
        Ok(())
    }

    fn verify_path(&self, p: PathBuf) -> PathBuf {
        if let Some(rest) = p.strip_prefix("~").ok() {
            let home = dirs::home_dir().expect("could not determine home directory");
            home.join(rest)
        } else {
            p
        }
    }

    fn launch_cd(&self, p: PathBuf) -> io::Result<()> {
        let path = self.verify_path(p);
        disable_raw_mode()?;
        println!("{}", path.display().to_string().trim());
        Ok(())
    }

    fn launch_edit(&mut self, p: PathBuf) -> io::Result<()> {
        let path = self.verify_path(p);
        _ = Command::new("nvim").arg(&path).exec();
        Ok(())
    }

    fn launch_open(&mut self, p: PathBuf) -> io::Result<()> {
        let path = self.verify_path(p);
        _ = Command::new("open").arg(&path).exec();
        Ok(())
    }
}
