import type { ButtonInteraction, StringSelectMenuInteraction } from 'discord.js';
import { t } from '@nexumi/shared';
import type { BotContext } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import {
  SELF_ROLE_BTN_PREFIX,
  SELF_ROLE_SEL_PREFIX,
  SelfRoleError,
  toggleSelfRole
} from './service.js';

export function isSelfRoleInteraction(customId: string): boolean {
  return customId.startsWith(SELF_ROLE_BTN_PREFIX) || customId.startsWith(SELF_ROLE_SEL_PREFIX);
}

function parseButtonCustomId(customId: string): { panelId: string; roleId: string } | null {
  if (!customId.startsWith(SELF_ROLE_BTN_PREFIX)) {
    return null;
  }

  const rest = customId.slice(SELF_ROLE_BTN_PREFIX.length);
  const colon = rest.indexOf(':');
  if (colon === -1) {
    return null;
  }

  const panelId = rest.slice(0, colon);
  const roleId = rest.slice(colon + 1);
  if (!panelId || !roleId) {
    return null;
  }

  return { panelId, roleId };
}

function parseSelectCustomId(customId: string): string | null {
  if (!customId.startsWith(SELF_ROLE_SEL_PREFIX)) {
    return null;
  }
  return customId.slice(SELF_ROLE_SEL_PREFIX.length) || null;
}

async function replySelfRoleResult(
  interaction: ButtonInteraction | StringSelectMenuInteraction,
  locale: 'de' | 'en',
  result: 'added' | 'removed' | 'unchanged',
  behavior: string
): Promise<void> {
  let key: string;
  if (result === 'added') {
    key = behavior === 'VERIFY' ? 'selfroles.role.verified' : 'selfroles.role.added';
  } else if (result === 'removed') {
    key = 'selfroles.role.removed';
  } else {
    key = 'selfroles.role.unchanged';
  }

  const content = t(locale, key);
  if (interaction.replied || interaction.deferred) {
    await interaction.followUp({ content, ephemeral: true });
  } else {
    await interaction.reply({ content, ephemeral: true });
  }
}

async function handleRoleToggle(
  interaction: ButtonInteraction | StringSelectMenuInteraction,
  context: BotContext,
  panelId: string,
  roleId: string
): Promise<void> {
  const locale = await getGuildLocale(context.prisma, interaction.guildId);
  if (!interaction.inGuild() || !interaction.guild) {
    await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
    return;
  }

  const panel = await context.prisma.selfRolePanel.findFirst({
    where: { id: panelId, guildId: interaction.guild.id }
  });

  if (!panel) {
    await interaction.reply({ content: t(locale, 'selfroles.error.not_found'), ephemeral: true });
    return;
  }

  const member = await interaction.guild.members.fetch(interaction.user.id).catch(() => null);
  if (!member) {
    await interaction.reply({ content: t(locale, 'selfroles.error.member_not_found'), ephemeral: true });
    return;
  }

  try {
    const result = await toggleSelfRole(context, panel, member, roleId);
    await replySelfRoleResult(interaction, locale, result, panel.behavior);
  } catch (error) {
    if (error instanceof SelfRoleError) {
      await interaction.reply({
        content: t(locale, `selfroles.error.${error.code}`),
        ephemeral: true
      });
      return;
    }
    throw error;
  }
}

export async function handleSelfRoleInteraction(
  interaction: ButtonInteraction | StringSelectMenuInteraction,
  context: BotContext
): Promise<void> {
  if (interaction.isButton()) {
    const parsed = parseButtonCustomId(interaction.customId);
    if (!parsed) {
      return;
    }
    await handleRoleToggle(interaction, context, parsed.panelId, parsed.roleId);
    return;
  }

  const panelId = parseSelectCustomId(interaction.customId);
  if (!panelId) {
    return;
  }

  const roleId = interaction.values[0];
  if (!roleId) {
    return;
  }

  await handleRoleToggle(interaction, context, panelId, roleId);
}
