use crate::{
cli::{ListToDo, SortToDo},
config::{Configuration, Language},
};
use itertools::Itertools;
use lib_tasker::todos::{State, Task, ToDo};
use owo_colors::OwoColorize;
use std::collections::HashSet;
pub fn get_index(to_do: &ToDo) -> usize {
match to_do.tasks.last() {
Some(last) => last.id + 1,
None => 0,
}
}
fn push_task(task: &Task, string: &mut String, config: &Configuration) {
string.push_str(&format!("{}. {}\n", task.id.purple(), task.description));
match config.language {
Language::English => match task.state {
State::ToDo => string.push_str(&format!("[{}] ", "To-Do".blue())),
State::Doing => {
string.push_str(&format!("[{}] ", "Doing".yellow()))
}
State::Done => string.push_str(&format!("[{}] ", "Done".green())),
State::Waiting => {
string.push_str(&format!("[{}] ", "Waiting".red()))
}
},
Language::Spanish => match task.state {
State::ToDo => {
string.push_str(&format!("[{}] ", "Por Hacer".blue()))
}
State::Doing => {
string.push_str(&format!("[{}] ", "Haciendo".yellow()))
}
State::Done => string.push_str(&format!("[{}] ", "Hecho".green())),
State::Waiting => {
string.push_str(&format!("[{}] ", "Esperando".red()))
}
},
}
string.push_str("{ ");
let tags = task.tags.iter().join(", ");
string.push_str(&tags);
string.push_str(" }\n\n");
}
pub fn list_tasks(to_do: ToDo, config: &Configuration, args: Option<ListToDo>) {
let mut output = String::new();
match args {
Some(options) => {
let mut tasks = to_do.tasks;
if let Some(description) = options.description {
tasks.retain(|task| {
task.description
.to_lowercase()
.contains(&description.to_lowercase())
});
}
if let Some(state) = options.state {
tasks.retain(|task| task.state == state.into());
}
if let Some(tags) = options.tag {
let tags: HashSet<String> = tags.into_iter().collect();
tasks.retain(|task| task.tags.intersection(&tags).count() > 0);
}
if let Some(project) = options.project {
tasks.retain(|task| {
task.project
.to_lowercase()
.contains(&project.to_lowercase())
});
}
if let Some(sort_options) = options.sort_by {
match sort_options {
SortToDo::Description => tasks.sort_unstable_by(|a, b| {
a.description
.to_lowercase()
.cmp(&b.description.to_lowercase())
}),
SortToDo::Project => tasks.sort_unstable_by(|a, b| {
a.project.to_lowercase().cmp(&b.project.to_lowercase())
}),
SortToDo::ID => {
tasks.sort_unstable_by(|a, b| a.id.cmp(&b.id))
}
SortToDo::State => {
tasks.sort_unstable_by(|a, b| a.state.cmp(&b.state))
}
}
}
tasks
.iter()
.for_each(|task| push_task(task, &mut output, config));
}
None => {
match config.language {
Language::English => output.push_str(&format!(
"Hello, {}!\nHere's what you got for today:\n",
config.name
)),
Language::Spanish => output.push_str(&format!(
"¡Hola, {}!\nEsto es lo que tienes para hoy:\n",
config.name
)),
}
output.push('\n');
let projects = to_do
.tasks
.iter()
.unique_by(|task| &task.project)
.map(|task| task.project.clone())
.sorted();
for project in projects {
output
.push_str(&format!("{}\n\n", project.purple().underline()));
to_do
.tasks
.iter()
.filter(|task| task.project == project)
.for_each(|task| push_task(task, &mut output, config));
}
}
}
print!("{output}");
}