use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use once_cell::sync::Lazy;
use rand::rngs::ThreadRng;
use rand::{Rng, RngCore};

#[derive(Debug, Clone)]
enum Action {
    AddProgressBar(usize),
    IncProgressBar(usize),
}

#[derive(Clone, Debug)]
struct Elem {
    key: String,
    index: usize,
    indent: usize,
    progress_bar: ProgressBar,
}

static ELEMENTS: Lazy<[Elem; 9]> = Lazy::new(|| {
    [
        Elem {
            indent: 1,
            index: 0,
            progress_bar: ProgressBar::new(32),
            key: "jumps".to_string(),
        },
        Elem {
            indent: 2,
            index: 1,
            progress_bar: ProgressBar::new(32),
            key: "lazy".to_string(),
        },
        Elem {
            indent: 0,
            index: 0,
            progress_bar: ProgressBar::new(32),
            key: "the".to_string(),
        },
        Elem {
            indent: 3,
            index: 3,
            progress_bar: ProgressBar::new(32),
            key: "dog".to_string(),
        },
        Elem {
            indent: 2,
            index: 2,
            progress_bar: ProgressBar::new(32),
            key: "over".to_string(),
        },
        Elem {
            indent: 2,
            index: 1,
            progress_bar: ProgressBar::new(32),
            key: "brown".to_string(),
        },
        Elem {
            indent: 1,
            index: 1,
            progress_bar: ProgressBar::new(32),
            key: "quick".to_string(),
        },
        Elem {
            indent: 3,
            index: 5,
            progress_bar: ProgressBar::new(32),
            key: "a".to_string(),
        },
        Elem {
            indent: 3,
            index: 3,
            progress_bar: ProgressBar::new(32),
            key: "fox".to_string(),
        },
    ]
});

/// The example implements the tree-like collection of progress bars, where elements are
/// added on the fly and progress bars get incremented until all elements is added and
/// all progress bars finished.
/// On each iteration `get_action` function returns some action, and when the tree gets
/// complete, the function returns `None`, which finishes the loop.
fn main() {
    let mp = Arc::new(MultiProgress::new());
    let sty_main = ProgressStyle::with_template("{bar:40.green/yellow} {pos:>4}/{len:4}").unwrap();
    let sty_aux = ProgressStyle::with_template("{spinner:.green} {msg} {pos:>4}/{len:4}").unwrap();

    let pb_main = mp.add(ProgressBar::new(
        ELEMENTS
            .iter()
            .map(|e| e.progress_bar.length().unwrap())
            .sum(),
    ));
    pb_main.set_style(sty_main);
    for elem in ELEMENTS.iter() {
        elem.progress_bar.set_style(sty_aux.clone());
    }

    let tree: Arc<Mutex<Vec<&Elem>>> = Arc::new(Mutex::new(Vec::with_capacity(ELEMENTS.len())));
    let tree2 = Arc::clone(&tree);

    let mp2 = Arc::clone(&mp);
    let _ = thread::spawn(move || {
        let mut rng = ThreadRng::default();
        pb_main.tick();
        loop {
            thread::sleep(Duration::from_millis(15));
            match get_action(&mut rng, &tree) {
                None => {
                    // all elements were exhausted
                    pb_main.finish();
                    return;
                }
                Some(Action::AddProgressBar(el_idx)) => {
                    let elem = &ELEMENTS[el_idx];
                    let pb = mp2.insert(elem.index + 1, elem.progress_bar.clone());
                    pb.set_message(format!("{}  {}", "  ".repeat(elem.indent), elem.key));
                    tree.lock().unwrap().insert(elem.index, elem);
                }
                Some(Action::IncProgressBar(el_idx)) => {
                    let elem = &tree.lock().unwrap()[el_idx];
                    elem.progress_bar.inc(1);
                    let pos = elem.progress_bar.position();
                    if pos >= elem.progress_bar.length().unwrap() {
                        elem.progress_bar.finish_with_message(format!(
                            "{}{} {}",
                            "  ".repeat(elem.indent),
                            "✔",
                            elem.key
                        ));
                    }
                    pb_main.inc(1);
                }
            }
        }
    })
    .join();

    println!("===============================");
    println!("the tree should be the same as:");
    for elem in tree2.lock().unwrap().iter() {
        println!("{}  {}", "  ".repeat(elem.indent), elem.key);
    }
}

/// The function guarantees to return the action, that is valid for the current tree.
fn get_action(rng: &mut dyn RngCore, tree: &Mutex<Vec<&Elem>>) -> Option<Action> {
    let elem_len = ELEMENTS.len() as u64;
    let list_len = tree.lock().unwrap().len() as u64;
    let sum_free = tree
        .lock()
        .unwrap()
        .iter()
        .map(|e| {
            let pos = e.progress_bar.position();
            let len = e.progress_bar.length().unwrap();
            len - pos
        })
        .sum::<u64>();

    if sum_free == 0 && list_len == elem_len {
        // nothing to do more
        None
    } else if sum_free == 0 && list_len < elem_len {
        // there is no place to make an increment
        Some(Action::AddProgressBar(tree.lock().unwrap().len()))
    } else {
        loop {
            let list = tree.lock().unwrap();
            let k = rng.gen_range(0..17);
            if k == 0 && list_len < elem_len {
                return Some(Action::AddProgressBar(list.len()));
            } else {
                let l = (k % list_len) as usize;
                let pos = list[l].progress_bar.position();
                let len = list[l].progress_bar.length();
                if pos < len.unwrap() {
                    return Some(Action::IncProgressBar(l));
                }
            }
        }
    }
}
