const core = require(`${global.dir}launch/core.js`);

const info = core.config.get(module.filename);
const config = info.command_config;
const command_prefix = core.config.manager.command.config.prefix;

module.exports.run = (client, user, message, content, args) => {
    message.reply((args.split.length > 0)
        ? show(args.split[0], message.author.id)
        : showAll(message.author.id)
    );
};

function showAll(userId) {
    core.log.verbose(info.log.all.start, "{user}", userId);
    let list = new Map();
    let reply = config.reply.all;
    let isOwner = core.botty.owner.isUser(userId);
    core.config.manager.command.storage.forEach((command) => {
        if (isOwner || !(core.botty.owner.isCommand(command)))
            list.set(
                `${command.file.type}${core.id.config.separator.type}${command.file.name}`,
                makeCommand(command, reply)
            );
    });
    list = makeCategory(list);
    let content = [];
    list.forEach((value, key) => {
        content.push(
            core.args(
                reply.category.line,
                "{name}", key,
                "{content}", showCategory(value)
            ));
    });
    content = content.join(reply.category.separator);
    core.log.verbose(info.log.all.end, "{user}", userId);
    return core.args(reply.message,
        "{list}", content);
}

function showCategory(list) {
    return list.join(config.reply.all.command.separator);
}

function makeCommand(command, reply) {
    let alias = [];
    command.alias.slice(1).forEach((a) => alias.push(
        core.args(reply.alias.line,
            "{alias}", a,
            "{prefix}", command_prefix)
    ));
    alias = alias.join(reply.alias.separator);
    let result = reply.command.line;
    if ((reply.alias.addition) && (command.alias.length > 1))
        result += reply.alias.addition;
    return core.args(result,
        "{name}", `${command.file.type}${core.id.config.separator.type}${command.file.name}`,
        "{usage}", `${command_prefix}${command.alias[0]}${
        command.help.usage.length === 0
            ? ` ${command.help.usage}`
            : ``}`,
        "{alias}", alias,
        "{description}", command.help.description);
}

function show(command, userId) {
    core.log.verbose(info.log.command.start, "{user}", userId, "{command}", command);
    let id = command.split(core.id.config.separator.type);
    let command_info = core.config.manager.getSafeByUnitInfo({
        type: `command${core.id.config.separator.name}${id[0]}`,
        name: id[1]
    });
    let reply = config.reply.command;
    if ((command_info === null)
        || (!core.botty.owner.isUser(userId) && core.botty.owner.isCommand(command_info.config)))
        return core.args(reply.failed, "{command}", command);
    core.log.verbose(info.log.command.start, "{user}", userId, "{command}", command);
    return core.args(reply.message,
        "{info}", makeCommand(command_info.config, reply));
}

function makeCategory(list) {
    let category = new Map();
    list.forEach((command, type) => {
        type = type
            .split(core.id.config.separator.type)[0]
            .split(core.id.config.separator.name)[0];
        let current = category.get(type);
        if (!current)
            category.set(type, [command]);
        else
            current.push(command);
    });
    return category;
}