text: const { User } = require('../../db/models/User');
  const { Config } = require('../../db/models/Config');
  const { MessageEmbed } = require('discord.js');
  
  /**
   * @param {import('discord.js').Client} client
   * @param {import('discord.js').Message} message
   * @param {Array<string>} args
   * @returns {Promise<void>}
   */
   exports.run = async (client, message, args) => {
    try {
      const allowedQueries = ['add', 'update', 'delete'];
      const query = args[0]?.toLowerCase();
  
      const user = await User.findOne({ id: message.author.id }) || await (new User({
        tag: message.author.tag,
        id: message.author.id,
        wins: 0,
        losses: 0,
        winrate: '0%'
      })).save();
  
      const guildCFG = await Config.findOne({ guildID: message.guildId })
        || await (new Config({ guildID: message.guildId })).save();
  
      if(!allowedQueries.includes(query)) {
        const embed = new MessageEmbed()
          .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
          .setColor('#ff0000')
          .setDescription(`Please provide a valid sub-command. Valid subcommands: ${
            allowedQueries.reduce((str, _query, index) => str += `\`${_query}\`${index < allowedQueries.length - 1 ? ', ' : ''}`, '')
          }`);
  
        return message.channel.send({ embeds: [ embed ] });
      }
  
      switch(query) {
        case 'add': {
          const roleID = args[1];
  
          if(!roleID || !(/\d{10,20}/.test(roleID))) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription('Please provide a valid role ID. Please [click here](https://www.remote.tools/remote-work/how-to-find-discord-id) if you do not know how to copy a role\'s ID!');
  
            return message.channel.send({ embeds: [ embed ] });
          }
  
          const role = await message.guild.roles.fetch(roleID);
  
          if(!role) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription(`Could not find the given role by ID, please make sure the role exists!`);
  
            return message.channel.send({ embeds: [ embed ] });
          }
  
          if(role.id === guildCFG.adminRole || role.id === guildCFG.wardenRole) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription(`You are not allowed to use that as a personal role!`);
  
            return message.channel.send({ emebds: [ embed ] });
          }
  
          if(role.position > message.guild.me.roles.highest.position) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription('I can not give this role since the role is ranked higher than my highest ranked role!');
  
            return message.channel.send({ embeds: [ embed ] });
          }
  
          if(role.position > message.member.roles.highest.position) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription('I can not give you this role because it is ranked higher than your highest ranked role!');
  
            return message.channel.send({ embeds: [ embed ] });
          }
  
          if(!message.member.roles.cache.has(roleID)) {
            message.member.roles.add(roleID);
          }
  
          user.personalRole = roleID;
          await user.save();
  
          const embed = new MessageEmbed()
            .setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
            .setColor('#2ae600')
            .setDescription(`Set the role **${role.name}** as your personal role`);
  
          message.channel.send({ embeds: [ embed ] });
        } break;
  
        case 'update': {
          const allowedKeys = ['color', 'name'];
          const key = args[1]?.toLowerCase();
  
          if(!role) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription(`Could not find your personal role, please use ${client.prefix}p-role add <roleID>`);
  
            return message.channel.send({ embeds: [ embed ] });
          }
  
          if(!allowedKeys.includes(key)) {
            const embed = new MessageEmbed()
              .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
              .setColor('#ff0000')
              .setDescription(`Please use a valid key. Valid keys: ${
                allowedKeys.reduce((str, _key, index) => str += `\`${_key}\`${index < allowedKeys.length - 1 ? ', ' : ''}`, '')
              }`);
  
            return message.channel.send({ embeds: [ embed ] })
          }
  
          const role = await message.guild.roles.fetch(user.personalRole);
  
          switch(key) {
            case 'color': {
              const colorInput = args[2];
  
              if(!(/#?([0-9A-F]{0,6})/i.test(colorInput))) {
                const embed = new MessageEmbed()
                  .setAuthor('ERROR!', message.author.displayAvatarURL({ dynamic: true }))
                  .setColor('#ff0000')
                  .setDescription('Invalid hex color! [Guide](https://www.hexcolortool.com/)');
  
                return message.channel.send({ embeds: [ embed ] });
              }
  
              const colorNum = parseInt(
                colorInput.startsWith('#') ? colorInput.slice(1) : colorInput,
                16
              );
  
              const color = colorNum < 0x01
                ? 0x01
                : colorNum > 0xFFFFFF
                  ? 0xFFFFFF
                  : colorNum;
  
              await role.setColor(color);
  
              const embed = new MessageEmbed()
                .setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
                .setColor(color)
                .setDescription(`Set the color to \`#${color.toString(16)}\` on your personal role **${role.name}**`)
  
              message.channel.send({ embeds: [ embed ] });
            } break;
  
            case 'name': {
              const nameInput = args.slice(2).join(' ');
              role.setName(nameInput);
  
              const embed = new MessageEmbed()
                .setAuthor(message.author.tag, message.author.displayAvatarURL({ dynamic: true }))
                .setColor('#2ae600')
                .setDescription(`Set the name to \`${nameInput}\` on your personal role **${role.name}**`);
  
              message.channel.send({ embeds: [ embed ] });
            } break;
          }
        } break;
      }
    } catch (err) {
      console.error(err);
    }
  }
  
  exports.help = {
    name: 'personal-role',
    description: 'Modifies your personal role',
    aliases: ['p-role']
  }
  