import {
  ActionRowBuilder,
  ModalBuilder,
  TextInputBuilder,
  TextInputStyle,
  type ButtonInteraction,
  type ModalSubmitInteraction,
  type VoiceChannel
} from 'discord.js';
import { t, tf } from '@nexumi/shared';
import type { BotContext } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import {
  assertTempVoiceOwner,
  claimTempChannel,
  hideTempChannel,
  kickFromTempChannel,
  lockTempChannel,
  parseTempVoiceButton,
  parseTempVoiceModal,
  tempVoiceModalId,
  TV_BUTTON_PREFIX,
  TV_MODAL_PREFIX,
  transferTempChannelOwnership
} from './service.js';

export function isTempVoiceInteraction(customId: string): boolean {
  return customId.startsWith(TV_BUTTON_PREFIX);
}

export function isTempVoiceModal(customId: string): boolean {
  return customId.startsWith(TV_MODAL_PREFIX);
}

async function showRenameModal(interaction: ButtonInteraction, channelId: string): Promise<void> {
  const modal = new ModalBuilder()
    .setCustomId(tempVoiceModalId('rename', channelId))
    .setTitle('Rename channel')
    .addComponents(
      new ActionRowBuilder<TextInputBuilder>().addComponents(
        new TextInputBuilder()
          .setCustomId('name')
          .setLabel('New name')
          .setStyle(TextInputStyle.Short)
          .setRequired(true)
          .setMaxLength(100)
      )
    );
  await interaction.showModal(modal);
}

async function showLimitModal(interaction: ButtonInteraction, channelId: string): Promise<void> {
  const modal = new ModalBuilder()
    .setCustomId(tempVoiceModalId('limit', channelId))
    .setTitle('Set user limit')
    .addComponents(
      new ActionRowBuilder<TextInputBuilder>().addComponents(
        new TextInputBuilder()
          .setCustomId('limit')
          .setLabel('Limit (0 = unlimited)')
          .setStyle(TextInputStyle.Short)
          .setRequired(true)
          .setMaxLength(2)
      )
    );
  await interaction.showModal(modal);
}

async function showKickModal(interaction: ButtonInteraction, channelId: string): Promise<void> {
  const modal = new ModalBuilder()
    .setCustomId(tempVoiceModalId('kick', channelId))
    .setTitle('Kick user')
    .addComponents(
      new ActionRowBuilder<TextInputBuilder>().addComponents(
        new TextInputBuilder()
          .setCustomId('user_id')
          .setLabel('User ID')
          .setStyle(TextInputStyle.Short)
          .setRequired(true)
          .setMaxLength(20)
      )
    );
  await interaction.showModal(modal);
}

async function showTransferModal(interaction: ButtonInteraction, channelId: string): Promise<void> {
  const modal = new ModalBuilder()
    .setCustomId(tempVoiceModalId('transfer', channelId))
    .setTitle('Transfer ownership')
    .addComponents(
      new ActionRowBuilder<TextInputBuilder>().addComponents(
        new TextInputBuilder()
          .setCustomId('user_id')
          .setLabel('New owner user ID')
          .setStyle(TextInputStyle.Short)
          .setRequired(true)
          .setMaxLength(20)
      )
    );
  await interaction.showModal(modal);
}

async function handleTempVoiceButton(
  interaction: ButtonInteraction,
  context: BotContext,
  locale: 'de' | 'en'
): Promise<void> {
  const parsed = parseTempVoiceButton(interaction.customId);
  if (!parsed || !interaction.inGuild()) {
    return;
  }

  const member = await interaction.guild!.members.fetch(interaction.user.id);
  const owned = await assertTempVoiceOwner(context, member, parsed.channelId);

  if (parsed.action === 'claim') {
    const channel = interaction.guild!.channels.cache.get(parsed.channelId);
    if (!channel?.isVoiceBased() || channel.isDMBased()) {
      await interaction.reply({ content: t(locale, 'tempvoice.error.notFound'), ephemeral: true });
      return;
    }
    const record = await context.prisma.tempVoiceChannel.findUnique({ where: { channelId: parsed.channelId } });
    if (!record) {
      await interaction.reply({ content: t(locale, 'tempvoice.error.notFound'), ephemeral: true });
      return;
    }
    const result = await claimTempChannel(context, record, channel as VoiceChannel, member, locale);
    if (result === 'owner_present') {
      await interaction.reply({ content: t(locale, 'tempvoice.claim.ownerPresent'), ephemeral: true });
      return;
    }
    if (result === 'not_in_channel') {
      await interaction.reply({ content: t(locale, 'tempvoice.error.notInChannel'), ephemeral: true });
      return;
    }
    await interaction.reply({ content: t(locale, 'tempvoice.claim.success'), ephemeral: true });
    return;
  }

  if (!owned) {
    await interaction.reply({ content: t(locale, 'tempvoice.error.notOwner'), ephemeral: true });
    return;
  }

  switch (parsed.action) {
    case 'rename':
      await showRenameModal(interaction, parsed.channelId);
      return;
    case 'limit':
      await showLimitModal(interaction, parsed.channelId);
      return;
    case 'kick':
      await showKickModal(interaction, parsed.channelId);
      return;
    case 'transfer':
      await showTransferModal(interaction, parsed.channelId);
      return;
    case 'lock':
      await lockTempChannel(owned.channel);
      await interaction.reply({ content: t(locale, 'tempvoice.lock.success'), ephemeral: true });
      return;
    case 'hide':
      await hideTempChannel(owned.channel);
      await interaction.reply({ content: t(locale, 'tempvoice.hide.success'), ephemeral: true });
      return;
    default:
      await interaction.reply({ content: t(locale, 'generic.error'), ephemeral: true });
  }
}

async function handleTempVoiceModal(
  interaction: ModalSubmitInteraction,
  context: BotContext,
  locale: 'de' | 'en'
): Promise<void> {
  const parsed = parseTempVoiceModal(interaction.customId);
  if (!parsed || !interaction.inGuild()) {
    return;
  }

  const member = await interaction.guild!.members.fetch(interaction.user.id);
  const owned = await assertTempVoiceOwner(context, member, parsed.channelId);
  if (!owned) {
    await interaction.reply({ content: t(locale, 'tempvoice.error.notOwner'), ephemeral: true });
    return;
  }

  if (parsed.action === 'rename') {
    const name = interaction.fields.getTextInputValue('name').trim();
    if (!name) {
      await interaction.reply({ content: t(locale, 'tempvoice.error.invalidName'), ephemeral: true });
      return;
    }
    await owned.channel.setName(name.slice(0, 100));
    await interaction.reply({
      content: tf(locale, 'tempvoice.rename.success', { name: name.slice(0, 100) }),
      ephemeral: true
    });
    return;
  }

  if (parsed.action === 'limit') {
    const raw = interaction.fields.getTextInputValue('limit').trim();
    const limit = Number.parseInt(raw, 10);
    if (Number.isNaN(limit) || limit < 0 || limit > 99) {
      await interaction.reply({ content: t(locale, 'tempvoice.error.invalidLimit'), ephemeral: true });
      return;
    }
    await owned.channel.setUserLimit(limit);
    await interaction.reply({
      content: tf(locale, 'tempvoice.limit.success', { limit }),
      ephemeral: true
    });
    return;
  }

  if (parsed.action === 'kick') {
    const userId = interaction.fields.getTextInputValue('user_id').trim();
    if (userId === interaction.user.id) {
      await interaction.reply({ content: t(locale, 'tempvoice.kick.self'), ephemeral: true });
      return;
    }
    const ok = await kickFromTempChannel(owned.channel, userId);
    if (!ok) {
      await interaction.reply({ content: t(locale, 'tempvoice.kick.notInChannel'), ephemeral: true });
      return;
    }
    await interaction.reply({
      content: tf(locale, 'tempvoice.kick.success', { user: `<@${userId}>` }),
      ephemeral: true
    });
    return;
  }

  if (parsed.action === 'transfer') {
    const userId = interaction.fields.getTextInputValue('user_id').trim();
    if (userId === interaction.user.id) {
      await interaction.reply({ content: t(locale, 'tempvoice.transfer.self'), ephemeral: true });
      return;
    }
    const target = await interaction.guild!.members.fetch(userId).catch(() => null);
    if (!target || !owned.channel.members.has(target.id)) {
      await interaction.reply({ content: t(locale, 'tempvoice.transfer.notInChannel'), ephemeral: true });
      return;
    }
    await transferTempChannelOwnership(context, owned.record, owned.channel, target, locale);
    await interaction.reply({
      content: tf(locale, 'tempvoice.transfer.success', { user: `<@${userId}>` }),
      ephemeral: true
    });
  }
}

export async function handleTempVoiceInteraction(
  interaction: ButtonInteraction | ModalSubmitInteraction,
  context: BotContext
): Promise<void> {
  const locale = await getGuildLocale(context.prisma, interaction.guildId);

  if (interaction.isButton()) {
    await handleTempVoiceButton(interaction, context, locale);
    return;
  }

  if (interaction.isModalSubmit() && interaction.customId.startsWith(TV_MODAL_PREFIX)) {
    await handleTempVoiceModal(interaction, context, locale);
  }
}
