import {
  SlashCommandBuilder,
  type SlashCommandAttachmentOption,
  type SlashCommandChannelOption,
  type SlashCommandRoleOption,
  type SlashCommandStringOption,
  type SlashCommandUserOption
} from 'discord.js';
import {
  applyCommandDescription,
  applyOptionDescription,
  type CommandLocaleKey
} from '@nexumi/shared';

function userOpt(o: SlashCommandUserOption, key: CommandLocaleKey = 'utility.common.options.userOptional') {
  return applyOptionDescription(o.setName('user'), key);
}

function channelOpt(o: SlashCommandChannelOption) {
  return applyOptionDescription(o.setName('channel'), 'utility.common.options.channelOptional');
}

function roleOpt(o: SlashCommandRoleOption) {
  return applyOptionDescription(o.setName('role').setRequired(true), 'utility.roleinfo.options.role');
}

function attachmentOpt(o: SlashCommandAttachmentOption) {
  return applyOptionDescription(o.setName('attachment'), 'utility.common.options.attachment');
}

function urlOpt(o: SlashCommandStringOption, key: CommandLocaleKey = 'utility.common.options.url') {
  return applyOptionDescription(o.setName('url'), key);
}

function nameOpt(o: SlashCommandStringOption, required = true) {
  const option = o.setName('name');
  if (required) {
    option.setRequired(true);
  }
  return applyOptionDescription(option, 'utility.common.options.name');
}

export const userinfoCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('userinfo'),
  'utility.userinfo.description'
).addUserOption((o) => userOpt(o));

export const serverinfoCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('serverinfo'),
  'utility.serverinfo.description'
);

export const roleinfoCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('roleinfo'),
  'utility.roleinfo.description'
).addRoleOption((o) => roleOpt(o));

export const channelinfoCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('channelinfo'),
  'utility.channelinfo.description'
).addChannelOption((o) => channelOpt(o));

export const avatarCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('avatar'),
  'utility.avatar.description'
).addUserOption((o) => userOpt(o));

export const bannerCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('banner'),
  'utility.banner.description'
).addUserOption((o) => userOpt(o));

export const pollCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('poll'),
  'utility.poll.description'
).addSubcommand((s) =>
  applyCommandDescription(s.setName('create'), 'utility.poll.create.description')
    .addStringOption((o) =>
      applyOptionDescription(o.setName('question').setRequired(true), 'utility.poll.options.question')
    )
    .addStringOption((o) =>
      applyOptionDescription(o.setName('options').setRequired(true), 'utility.poll.options.options')
    )
    .addBooleanOption((o) =>
      applyOptionDescription(o.setName('multiselect'), 'utility.poll.options.multiselect')
    )
    .addBooleanOption((o) =>
      applyOptionDescription(o.setName('anonymous'), 'utility.poll.options.anonymous')
    )
    .addStringOption((o) =>
      applyOptionDescription(o.setName('duration'), 'utility.poll.options.duration')
    )
);

export const remindmeCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('remindme'),
  'utility.remindme.description'
)
  .addStringOption((o) =>
    applyOptionDescription(o.setName('when').setRequired(true), 'utility.remindme.options.when')
  )
  .addStringOption((o) =>
    applyOptionDescription(o.setName('content').setRequired(true), 'utility.remindme.options.content')
  )
  .addStringOption((o) =>
    applyOptionDescription(o.setName('recurring_cron'), 'utility.remindme.options.recurring_cron')
  );

export const remindersCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('reminders'),
  'utility.reminders.description'
)
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('list'), 'utility.reminders.list.description')
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('delete'), 'utility.reminders.delete.description').addStringOption(
      (o) =>
        applyOptionDescription(o.setName('id').setRequired(true), 'utility.reminders.options.id')
    )
  );

export const afkCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('afk'),
  'utility.afk.description'
).addSubcommand((s) =>
  applyCommandDescription(s.setName('set'), 'utility.afk.set.description').addStringOption((o) =>
    applyOptionDescription(o.setName('reason'), 'utility.afk.options.reason')
  )
);

export const emojiCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('emoji'),
  'utility.emoji.description'
)
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('add'), 'utility.emoji.add.description')
      .addStringOption((o) => nameOpt(o))
      .addAttachmentOption((o) => attachmentOpt(o))
      .addStringOption((o) => urlOpt(o, 'utility.emoji.options.url'))
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('remove'), 'utility.emoji.remove.description').addStringOption((o) =>
      applyOptionDescription(o.setName('emoji').setRequired(true), 'utility.emoji.options.emoji')
    )
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('steal'), 'utility.emoji.steal.description').addStringOption((o) =>
      applyOptionDescription(o.setName('message_id').setRequired(true), 'utility.emoji.options.message_id')
    )
  );

export const stickerCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('sticker'),
  'utility.sticker.description'
).addSubcommand((s) =>
  applyCommandDescription(s.setName('add'), 'utility.sticker.add.description')
    .addStringOption((o) => nameOpt(o))
    .addAttachmentOption((o) => attachmentOpt(o))
    .addStringOption((o) => urlOpt(o, 'utility.sticker.options.url'))
);

export const timestampCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('timestamp'),
  'utility.timestamp.description'
).addStringOption((o) =>
  applyOptionDescription(o.setName('datetime').setRequired(true), 'utility.timestamp.options.datetime')
);

export const snipeCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('snipe'),
  'utility.snipe.description'
);

export const editsnipeCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('editsnipe'),
  'utility.editsnipe.description'
);

export const embedCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('embed'),
  'utility.embed.description'
)
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('builder'), 'utility.embed.builder.description')
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('components'), 'utility.embed.components.description')
      .addChannelOption((o) =>
        applyOptionDescription(
          o.setName('channel').setRequired(true),
          'utility.embed.components.options.channel'
        )
      )
      .addStringOption((o) =>
        applyOptionDescription(
          o.setName('text').setRequired(true).setMaxLength(2000),
          'utility.embed.components.options.text'
        )
      )
      .addStringOption((o) =>
        applyOptionDescription(
          o.setName('image_url').setMaxLength(2048),
          'utility.embed.components.options.image_url'
        )
      )
      .addStringOption((o) =>
        applyOptionDescription(
          o.setName('button_label').setMaxLength(80),
          'utility.embed.components.options.button_label'
        )
      )
      .addStringOption((o) =>
        applyOptionDescription(
          o.setName('button_url').setMaxLength(2048),
          'utility.embed.components.options.button_url'
        )
      )
  );
