use crate::{
    commands::{Cli, Config, Result},
    jobber::JobberIter,
    print_tip,
    views::{InvoiceView, create_invoice_table},
};
use clap::Parser;
use color_print::cprintln;

#[derive(Parser, Debug)]
pub(crate) struct ListInvoices {
    /// List only deleted invoices
    #[clap(short, long)]
    deleted: bool,
}

impl ListInvoices {
    pub(crate) fn run(&self, cli: &Cli) -> Result<()> {
        cprintln!();
        let config = Config::load()?;
        let database = cli.open_database()?;
        let deleted_str = if self.deleted { "deleted " } else { "" };
        let deleted = self.deleted.into();
        let num_invoices = database.iter_invoices(deleted).count();
        if num_invoices > 0 {
            let rows: Vec<_> = database
                .iter_invoices(deleted)
                .map(|(no, _)| InvoiceView::new(no, &database, cli.ansi()))
                .collect::<Result<_>>()?;
            let table = create_invoice_table(rows, &config);
            let hours: f64 = database
                .iter_invoices(deleted)
                .map(|(_, invoice)| invoice.hours())
                .sum();
            cprintln!("{table}");
            cprintln!();
            cprintln!("<s>{num_invoices}</> {deleted_str}invoice(s) = <s>{hours:.2} hours</>",);
            print_tip!(cli);
            if self.deleted {
                print_tip!(
                    cli,
                    "Use <s>jobber delete invoice --restore</> to restore a deleted invoice."
                );
            }
            print_tip!(cli, "Use <s>jobber show invoice</> to view an invoice.");
        } else {
            cprintln!("No {deleted_str}invoices.");
            print_tip!(cli);
            print_tip!(cli, "Use <s>jobber create invoice</> to create one.");
        }
        Ok(())
    }
}
