import { createPaginationEmbed } from 'eris-pagination';
import { Message } from 'eris';
import { Client, Command, RichEmbed } from '../class';

export default class Help extends Command {
  constructor(client: Client) {
    super(client);
    this.name = 'help';
    this.description = 'Information about commands.';
    this.usage = 'help [command]';
    this.permissions = 0;
    this.enabled = true;
    this.guildOnly = true;
  }

  public async run(message: Message, args: string[]) {
    try {
      if (args.length > 0) {
        const resolved = await this.client.util.resolveCommand(args, message);
        if (!resolved) return this.error(message.channel, 'The command you provided doesn\'t exist.');
        const { cmd } = resolved;
        const embed = new RichEmbed();
        const subcommands = cmd.subcommands.size ? `\n**Subcommands:** ${cmd.subcommands.map((s) => `${cmd.name} ${s.name}`).join(', ')}` : '';
        embed.setTitle(`${this.client.config.prefix}${cmd.name}`);
        embed.addField('Description', cmd.description ?? '-');
        embed.addField('Usage', cmd.usage ?? '-');
        if (subcommands) embed.addField('Sub-commands', subcommands);
        if (cmd.aliases.length > 0) {
          embed.addField('Aliases', cmd.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '));
        }
        let description: string = '';
        if (!cmd.enabled) {
          description += 'This command is disabled.';
        }
        if (cmd.guildOnly) {
          description += 'This command can only be ran in a guild.';
        }
        embed.setDescription(description);
        switch (cmd.permissions) {
          case 0:
            break;
          case 1:
            embed.addField('Permissions', 'Associates+');
            break;
          case 2:
            embed.addField('Permissions', 'Core Team+');
            break;
          case 3:
            embed.addField('Permissions', 'Moderators, Supervisor, & Board of Directors');
            break;
          case 4:
            embed.addField('Permissions', 'Technicians, Supervisor, & Board of Directors');
            break;
          case 5:
            embed.addField('Permissions', 'Moderators, Technicians, Supervisor, & Board of Directors');
            break;
          case 6:
            embed.addField('Permissions', 'Supervisor+');
            break;
          case 7:
            embed.addField('Permissions', 'Board of Directors');
            break;
          default:
            break;
        }
        embed.setFooter(this.client.user.username, this.client.user.avatarURL);
        embed.setTimestamp();
        return message.channel.createMessage({ embed });
      }
      const cmdList: Command[] = [];
      this.client.commands.forEach((c) => {
        if (c.permissions !== 0 && c.guildOnly) {
          const check = c.checkCustomPermissions(message.member, c.permissions);
          if (!check) return;
        }
        cmdList.push(c);
      });
      const commands = this.client.commands.map((c) => {
        const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', ');
        let perm: string;
        switch (c.permissions) {
          case 0:
            break;
          case 1:
            perm = 'Associates+';
            break;
          case 2:
            perm = 'Core Team+';
            break;
          case 3:
            perm = 'Moderators, Supervisor, & Board of Directors';
            break;
          case 4:
            perm = 'Technicians, Supervisor, & Board of Directors';
            break;
          case 5:
            perm = 'Moderators, Technicians, Supervisor, & Board of Directors';
            break;
          case 6:
            perm = 'Supervisor+';
            break;
          case 7:
            perm = 'Board of Directors';
            break;
          default:
            break;
        }
        return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n**Permissions:** ${perm ?? ''}`, inline: false };
      });
      const splitCommands = this.client.util.splitFields(commands);
      const cmdPages: RichEmbed[] = [];
      splitCommands.forEach((splitCmd) => {
        const embed = new RichEmbed();
        embed.setTimestamp(); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
        embed.setDescription(`Command list for ${this.client.user.username}`);
        splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline));
        return cmdPages.push(embed);
      });
      if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
      return createPaginationEmbed(message, cmdPages);
    } catch (err) {
      return this.client.util.handleError(err, message, this, false);
    }
  }
}
