import { MessageFlags, PermissionFlagsBits, type InteractionReplyOptions } from 'discord.js';
import { t } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { requirePermission } from '../../permissions.js';
import { welcomeCommandData } from './command-definitions.js';
import { getWelcomeConfig, resolveWelcomePayload } from './service.js';
import { buildWelcomeMessage } from './renderer.js';

function toInteractionReply(
  message: Awaited<ReturnType<typeof buildWelcomeMessage>>,
  ephemeral: boolean
): InteractionReplyOptions {
  const flags =
    typeof message.flags === 'number'
      ? ephemeral
        ? message.flags | MessageFlags.Ephemeral
        : message.flags
      : undefined;

  return {
    content: message.content,
    embeds: message.embeds,
    files: message.files,
    components: message.components,
    ...(flags !== undefined ? { flags } : ephemeral ? { ephemeral: true } : {})
  };
}

const welcomeCommand: SlashCommand = {
  data: welcomeCommandData,
  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 config = await getWelcomeConfig(context.prisma, interaction.guildId!);
    const sub = interaction.options.getSubcommand();
    const member = interaction.member;
    if (!member || !('guild' in member)) {
      await interaction.reply({ content: t(locale, 'generic.error'), ephemeral: true });
      return;
    }

    const guildMember = await interaction.guild!.members.fetch(interaction.user.id);
    const payload = resolveWelcomePayload(config);

    if (sub === 'preview') {
      const message = await buildWelcomeMessage(payload, guildMember, interaction.guild!);
      await interaction.reply(toInteractionReply(message, true));
      return;
    }

    if (!config.welcomeChannelId) {
      await interaction.reply({ content: t(locale, 'welcome.notConfigured'), ephemeral: true });
      return;
    }

    const channel = await interaction.guild!.channels.fetch(config.welcomeChannelId);
    if (!channel?.isTextBased() || channel.isDMBased()) {
      await interaction.reply({ content: t(locale, 'welcome.invalidChannel'), ephemeral: true });
      return;
    }

    const message = await buildWelcomeMessage(payload, guildMember, interaction.guild!);
    if ('send' in channel) {
      await channel.send(message);
    }
    await interaction.reply({ content: t(locale, 'welcome.testSent'), ephemeral: true });
  }
};

export const welcomeCommands: SlashCommand[] = [welcomeCommand];
