use inquire::{MultiSelect, Select, Text};
use crossterm::terminal;

use super::printers::{clear_console, inform_delay, print_boxed, StatementType};

const DELAY_SECONDS: u64 = 1;

pub fn ask_mcq_delayed(question: &str, options: &[&str]) -> Option<String> {
    print_boxed(question, StatementType::Question);
    inform_delay(DELAY_SECONDS);
    std::thread::sleep(std::time::Duration::from_secs(DELAY_SECONDS));
    ask_mcq(question, options)
}

/// Print a quiz question in an attractive format and get the user's choice
pub fn ask_mcq(question: &str, options: &[&str]) -> Option<String> {

    clear_console();

    // Calculate vertical centering
    let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - options.len() - 2;

    print_boxed(&format!("{}", question), StatementType::Question);

    for _ in 0..(rows/2) {
        println!();
    }

    let ans = Select::new("Your response:", options.to_vec())
        .prompt();

    match ans {
        Ok(choice) => Some(String::from(choice)),
        Err(_) => None,
    }
}

/// Print a quiz question in an attractive format and get the user's choices
pub fn ask_multi_select(question: &str, options: &[&str]) -> Option<Vec<String>> {

    clear_console();

    // Calculate vertical centering
    let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - options.len() - 2;

    print_boxed(&format!("{}", question), StatementType::Question);

    for _ in 0..(rows/2) {
        println!();
    }

    let ans = MultiSelect::new("Select all applicable answers with SPACEBAR, then press RETURN to submit:", options.to_vec())
        .prompt();

    match ans {
        Ok(choices) => Some(choices.into_iter().map(String::from).collect()),
        Err(_) => None,
    }
}

/// Print a question in an attractive format and get the user's text input
pub fn ask_plaintext(question: &str) -> Option<String> {

    clear_console();

    // Calculate vertical centering
    let rows = terminal::size().map(|(_, height)| height as usize).unwrap_or(0) - 3;

    print_boxed(&format!("{}", question), StatementType::Question);

    for _ in 0..(rows/2) {
        println!();
    }

    let ans = Text::new("Please provide your input:")
        .prompt();

    match ans {
        Ok(choice) => Some(choice),
        Err(_) => None,
    }
}

pub fn ask_name() -> String {
    let name = ask_plaintext("What is your name?").unwrap_or_else(|| {
        let default_name = super::generators::generate_name();
        print_boxed(&format!("Failed to get name. I'll give you a random one: {}.", default_name), StatementType::IncorrectFeedback);
        default_name
    });
    if name .is_empty() {
        let default_name = super::generators::generate_name();
        print_boxed(&format!("You didn't provide a name. I'll give you a random one: {}.", default_name), StatementType::IncorrectFeedback);
        return default_name;
    }
    print_boxed(&format!("Welcome, {}! Thanks for joining me.", name), StatementType::Default);
    name
}