import { PermissionFlagsBits } from 'discord.js';
import { t, tf } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { requirePermission } from '../../permissions.js';
import { suggestCommandData, suggestionCommandData } from './command-definitions.js';
import {
  createSuggestion,
  SuggestionError,
  updateSuggestionConfig,
  updateSuggestionStatus
} from './service.js';

const suggestCommand: SlashCommand = {
  data: suggestCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    if (!interaction.inGuild()) {
      await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
      return;
    }

    const content = interaction.options.getString('content', true);
    await interaction.deferReply({ ephemeral: true });

    try {
      const suggestion = await createSuggestion(
        context,
        {
          guildId: interaction.guildId!,
          authorId: interaction.user.id,
          content
        },
        locale
      );
      await interaction.editReply({
        content: tf(locale, 'suggestion.created', { id: suggestion.id })
      });
    } catch (error) {
      if (error instanceof SuggestionError) {
        await interaction.editReply({
          content: t(locale, `suggestion.error.${error.code}`)
        });
        return;
      }
      throw error;
    }
  }
};

const suggestionCommand: SlashCommand = {
  data: suggestionCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    if (!interaction.inGuild()) {
      await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
      return;
    }
    if (!(await requirePermission(interaction, PermissionFlagsBits.ManageGuild, locale))) {
      return;
    }

    const guildId = interaction.guildId!;
    const sub = interaction.options.getSubcommand();

    if (sub === 'setup') {
      const openChannel = interaction.options.getChannel('open_channel', true);
      const approvedChannel = interaction.options.getChannel('approved_channel');
      const deniedChannel = interaction.options.getChannel('denied_channel');
      const createThread = interaction.options.getBoolean('create_thread') ?? true;

      await updateSuggestionConfig(context.prisma, guildId, {
        enabled: true,
        openChannelId: openChannel.id,
        approvedChannelId: approvedChannel?.id ?? null,
        deniedChannelId: deniedChannel?.id ?? null,
        createThread
      });

      await interaction.reply({ content: t(locale, 'suggestion.setupDone'), ephemeral: true });
      return;
    }

    const suggestionId = interaction.options.getString('suggestion_id', true);
    const reason = interaction.options.getString('reason', true);
    const statusMap = {
      approve: 'APPROVED',
      deny: 'DENIED',
      consider: 'CONSIDERED',
      implement: 'IMPLEMENTED'
    } as const;

    try {
      await updateSuggestionStatus(
        context,
        {
          suggestionId,
          guildId,
          status: statusMap[sub as keyof typeof statusMap],
          reason
        },
        locale
      );
      await interaction.reply({
        content: tf(locale, 'suggestion.staffUpdated', { status: sub }),
        ephemeral: true
      });
    } catch (error) {
      if (error instanceof SuggestionError) {
        await interaction.reply({
          content: t(locale, `suggestion.error.${error.code}`),
          ephemeral: true
        });
        return;
      }
      throw error;
    }
  }
};

export const suggestionsCommands: SlashCommand[] = [suggestCommand, suggestionCommand];
