use std::collections::HashMap;

use crate::{
    commands::{Cli, Config, Result, edit::edit_job},
    jobber::{Deleted, JobberCreate, JobberIter},
    print_tip,
    views::JobView,
};
use clap::Parser;
use color_print::cprintln;
use inquire::Confirm;

/// Create a new job of an existing worker for an existing client.
#[derive(Parser, Debug)]
pub(crate) struct CreateJob {
    /// Do not select new job
    #[clap(short, long)]
    no_select: bool,
}

impl CreateJob {
    pub(crate) fn run(&self, cli: &Cli) -> Result<()> {
        let mut config = Config::load()?;
        let mut database = cli.open_database()?;
        let mut job_id = None;
        loop {
            let workers: Vec<_> = database
                .iter_workers(Deleted::All)
                .map(|(id, _)| id.clone())
                .collect();
            let clients: HashMap<_, _> = database
                .iter_clients(Deleted::All)
                .map(|(id, client)| (id.clone(), client.scheme.clone()))
                .collect();
            if !database.create_job(job_id, |job| edit_job(job, workers, clients))? {
                cprintln!("Nothing changed.");
                return Ok(());
            }
            let id = database.iter_jobs(Deleted::All).count() - 1;
            job_id = Some(id);
            println!();
            println!("{}", JobView::new(id, &config, &database, cli.ansi())?);
            match Confirm::new("Is this information correct?")
                .with_default(true)
                .with_help_message("cancel create with ESC")
                .prompt_skippable()?
            {
                Some(true) => {
                    if self.no_select {
                        cprintln!("Successfully created job {id}.");
                    } else {
                        config.set_current_job(id);
                        cprintln!("Successfully created and selected job {id}.");
                    }
                    print_tip!(cli);
                    print_tip!(cli, "Use <s>jobber show job</> to see the job data.");
                    print_tip!(cli, "Use <s>jobber undo</> to undo the change.");
                    cli.close_database(database)?;
                    return Ok(());
                }
                Some(false) => (),
                None => {
                    cprintln!("Database remained unchanged.");
                    return Ok(());
                }
            }
        }
    }
}
