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

function amountOpt(o: SlashCommandIntegerOption, key: CommandLocaleKey = 'economy.common.options.amount') {
  return applyOptionDescription(o.setName('amount').setRequired(true).setMinValue(1), key);
}

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

function optionalUserOpt(o: SlashCommandUserOption) {
  return applyOptionDescription(o.setName('user'), 'economy.common.options.userOptional');
}

function choiceOpt(o: SlashCommandStringOption) {
  return applyOptionDescription(o.setName('choice').setRequired(true), 'economy.coinflip.options.choice').addChoices(
    localizedChoice('economy.choice.heads', 'heads'),
    localizedChoice('economy.choice.tails', 'tails')
  );
}

export const balanceCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('balance'),
  'economy.balance.description'
).addUserOption((o) => optionalUserOpt(o));

export const dailyCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('daily'),
  'economy.daily.description'
);

export const weeklyCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('weekly'),
  'economy.weekly.description'
);

export const workCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('work'),
  'economy.work.description'
);

export const payCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('pay'),
  'economy.pay.description'
)
  .addUserOption((o) => userOpt(o))
  .addIntegerOption((o) => amountOpt(o));

export const gambleCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('gamble'),
  'economy.gamble.description'
).addIntegerOption((o) => amountOpt(o));

export const slotsCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('slots'),
  'economy.slots.description'
).addIntegerOption((o) => amountOpt(o));

export const blackjackCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('blackjack'),
  'economy.blackjack.description'
).addIntegerOption((o) => amountOpt(o));

export const coinflipCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('coinflip'),
  'economy.coinflip.description'
)
  .addIntegerOption((o) => amountOpt(o))
  .addStringOption((o) => choiceOpt(o));

export const shopCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('shop'),
  'economy.shop.description'
)
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('view'), 'economy.shop.view.description')
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('buy'), 'economy.shop.buy.description').addStringOption((o) =>
      applyOptionDescription(o.setName('item_id').setRequired(true), 'economy.shop.options.item_id')
    )
  );

export const inventoryCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('inventory'),
  'economy.inventory.description'
);

export const ecoCommandData = applyCommandDescription(
  new SlashCommandBuilder().setName('eco'),
  'economy.eco.description'
)
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('leaderboard'), 'economy.eco.leaderboard.description')
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('give'), 'economy.eco.give.description')
      .addUserOption((o) => userOpt(o, 'economy.common.options.target'))
      .addIntegerOption((o) => amountOpt(o))
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('remove'), 'economy.eco.remove.description')
      .addUserOption((o) => userOpt(o, 'economy.common.options.target'))
      .addIntegerOption((o) => amountOpt(o))
  )
  .addSubcommand((s) =>
    applyCommandDescription(s.setName('reset'), 'economy.eco.reset.description').addUserOption((o) =>
      userOpt(o, 'economy.common.options.target')
    )
  );
