use std::{
    fmt::Arguments,
    io::{self, Write},
};

use crate::{error, prompts::Prompter};

/// A very simple cli logger
#[derive(Debug)]
pub struct CliPrompter;

impl Prompter for CliPrompter {
    fn okay(&self, msg: Arguments) {
        let mut output = io::stdout();
        let _ = output.write_fmt(msg);
        let _ = output.write_all(b"\nPress [ENTER] to continue.\n");
        let _ = output.flush();
        let _ = io::stdin().read_line(&mut String::new());
    }

    fn ask(&self, msg: Arguments, default: bool) -> Option<bool> {
        let prompt = if default { "[Y/n]" } else { "[y/N]" };

        let mut output = io::stdout();
        loop {
            let _ = output.write_all(b"==> Confirmation\n");
            let _ = output.write_fmt(msg);
            let _ = output.write(b"\n");
            let _ = output.write_all(prompt.as_bytes());
            let _ = output.write(b"\n");
            let _ = output.flush();

            let mut input = String::new();
            io::stdin()
                .read_line(&mut input)
                .inspect_err(|err| error!("Could not read stdin: {err}"))
                .ok()?;

            match input.trim().to_ascii_lowercase().as_str() {
                "" => return Some(default),
                "y" | "yes" => return Some(true),
                "n" | "no" => return Some(false),
                _ => {
                    let _ = output.write_all(b"Please enter 'y' for yes or 'n' for no.");
                    let _ = output.flush();
                }
            }
        }
    }
}
