use super::*;
use schema::unit::dsl::*;
use serenity::builder::CreateMessage;

const STEP: usize = 80;
const STEP_SPLIT: usize = 2;
const TINY_STEP: usize = STEP / STEP_SPLIT;
const PADDING: &str = "\u{00a0}\u{00a0}\u{00a0}\u{00a0}\u{00a0}\u{00a0}";

#[command]
#[aliases("lst")]
#[description = "List unit registered in bot"]
#[max_args(1)]
#[usage = "[-c]\n\t-c\t\t# show result in current channel"]
fn list(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult {
    let conn = establish_connection();

    let units: Vec<String> = unit
        .select(name)
        .order(name.asc())
        .load::<String>(&conn)?
        .into_iter()
        .map(|n| n + PADDING)
        .collect();

    let mut offset: usize = 0;
    for chunk in units.chunks(STEP) {
        let fields: Vec<String> = chunk
            .chunks(STEP / STEP_SPLIT)
            .map(|c| c.join("\n"))
            .collect();

        let status = if args.message().contains("-c") {
            msg.channel_id.send_message(&ctx, |m| {
                format_output(m, &fields, offset);
                m
            })
        } else {
            msg.author.dm(&ctx, |m| {
                format_output(m, &fields, offset);
                m
            })
        };

        if let Err(e) = status {
            error!("[E031] Error during send unit list reply: {}", e)
        }

        offset += STEP;
    }

    Ok(())
}

fn format_output(m: &mut CreateMessage, fields: &[String], offset: usize) {
    m.embed(|e| {
        fields.iter().enumerate().for_each(|item| {
            e.field(
                format!(
                    "Units from {} to {}",
                    offset + TINY_STEP * item.0,
                    offset + TINY_STEP * (item.0 + 1)
                ),
                item.1,
                true,
            );
        });
        e
    });
}
