Skip to content
use crate::client::Client;
use crate::protocol::Request;

pub fn run(args: &[String]) {
    match args.first().map(String::as_str) {
        Some("add") => cmd_add(&args[1..]),
        Some("list" | "ls") => cmd_list(),
        Some("done") => cmd_done(&args[1..]),
        Some("remove" | "rm") => cmd_remove(&args[1..]),
        Some("clear") => cmd_clear(),
        Some("service") => crate::service::run_cli(&args[1..]),
        Some("help" | "--help" | "-h") => print_help(),
        Some(other) => {
            eprintln!("Unknown command: {other}");
            print_help();
            std::process::exit(1);
        }
        None => unreachable!(),
    }
}

fn send_or_exit(request: &Request) -> crate::protocol::Response {
    match Client::send(request) {
        Ok(resp) => {
            if !resp.ok {
                if let Some(msg) = &resp.message {
                    eprintln!("Error: {msg}");
                }
                std::process::exit(1);
            }
            resp
        }
        Err(e) => {
            eprintln!("{e}");
            std::process::exit(1);
        }
    }
}

fn cmd_add(args: &[String]) {
    if args.is_empty() {
        eprintln!("Usage: hyperfocus add <name> [duration_minutes]");
        eprintln!("  duration defaults to 25 minutes if omitted");
        std::process::exit(1);
    }

    let (name, duration) = if args.len() >= 2 {
        if let Ok(d) = args.last().unwrap().parse::<u32>() {
            (args[..args.len() - 1].join(" "), d)
        } else {
            (args.join(" "), 25)
        }
    } else {
        (args[0].clone(), 25)
    };

    send_or_exit(&Request::AddTask {
        name: name.clone(),
        duration_minutes: duration,
    });
    println!("Added: \"{name}\" ({duration}m)");
}

fn cmd_list() {
    let resp = send_or_exit(&Request::ListTasks);
    let tasks = resp.tasks.unwrap_or_default();

    if tasks.is_empty() {
        println!("No tasks. Add one with: hyperfocus add <name> [duration]");
        return;
    }

    println!("{:<4} {:<6} {:<8} Name", "#", "Done", "Minutes");
    println!("{}", "-".repeat(40));
    for (i, task) in tasks.iter().enumerate() {
        let check = if task.completed { "\u{2713}" } else { " " };
        println!(
            "{:<4} [{}]    {:<8} {}",
            i + 1,
            check,
            task.duration_minutes,
            task.name
        );
    }
}

fn cmd_done(args: &[String]) {
    let Some(idx_str) = args.first() else {
        eprintln!("Usage: hyperfocus done <task_number>");
        std::process::exit(1);
    };
    let Ok(idx) = idx_str.parse::<usize>() else {
        eprintln!("Invalid task number: {idx_str}");
        std::process::exit(1);
    };
    if idx == 0 {
        eprintln!("Task numbers start at 1");
        std::process::exit(1);
    }
    let resp = send_or_exit(&Request::MarkDone { index: idx - 1 });
    if let Some(msg) = resp.message {
        println!("{msg}");
    }
}

fn cmd_remove(args: &[String]) {
    let Some(idx_str) = args.first() else {
        eprintln!("Usage: hyperfocus remove <task_number>");
        std::process::exit(1);
    };
    let Ok(idx) = idx_str.parse::<usize>() else {
        eprintln!("Invalid task number: {idx_str}");
        std::process::exit(1);
    };
    if idx == 0 {
        eprintln!("Task numbers start at 1");
        std::process::exit(1);
    }
    let resp = send_or_exit(&Request::RemoveTask { index: idx - 1 });
    if let Some(msg) = resp.message {
        println!("{msg}");
    }
}

fn cmd_clear() {
    let resp = send_or_exit(&Request::ClearCompleted);
    if let Some(msg) = resp.message {
        println!("{msg}");
    }
}

fn print_help() {
    println!("Hyperfocus - Focus timer & task manager");
    println!();
    println!("USAGE:");
    println!("  hyperfocus                Launch the GUI");
    println!("  hyperfocus <command>      Run a CLI command");
    println!();
    println!("COMMANDS:");
    println!("  add <name> [minutes]     Add a task (default: 25 minutes)");
    println!("  list, ls                 List all tasks");
    println!("  done <number>            Mark a task as completed");
    println!("  remove, rm <number>      Remove a task");
    println!("  clear                    Remove all completed tasks");
    println!("  service <start|stop|status>");
    println!("                           Manage the background service");
    println!("  help                     Show this help");
}