use std::process;

use anyhow::Result;
use yazi_boot::ARGS;
use yazi_fs::engine::{Engine, local::Local};
use yazi_parser::app::QuitForm;
use yazi_shared::{data::Data, strand::{StrandBuf, StrandLike, ToStrand}};
use yazi_tui::Raterm;

use crate::{Actor, Ctx};

pub struct Quit;

impl Actor for Quit {
	type Form = QuitForm;

	const NAME: &str = "quit";

	fn act(cx: &mut Ctx, Self::Form { opt }: Self::Form) -> Result<Data> {
		cx.tasks.shutdown();
		cx.mgr.shutdown();

		futures::executor::block_on(async {
			_ = futures::join!(
				yazi_dds::shutdown(),
				yazi_dds::STATE.drain(),
				Self::cwd_to_file(cx, opt.no_cwd_file),
				Self::selected_to_file(opt.selected)
			);
		});

		Raterm::stop();
		process::exit(opt.code);
	}
}

impl Quit {
	async fn cwd_to_file(cx: &Ctx<'_>, no: bool) {
		if let Some(p) = ARGS.cwd_file.as_ref().filter(|_| !no) {
			let cwd = cx.mgr.cwd().to_strand();
			Local::regular(p).write(cwd.encoded_bytes()).await.ok();
		}
	}

	async fn selected_to_file(selected: Option<StrandBuf>) {
		if let (Some(s), Some(p)) = (selected, &ARGS.chooser_file) {
			Local::regular(p).write(s.encoded_bytes()).await.ok();
		}
	}
}
