import { MessageComponentInteraction, PermissionFlagsBits, ChannelType } from 'discord.js';
import { SetupWizardRenderer } from '../../services/SetupWizardRenderer';
import { SupportedLocale, t } from '../../i18n';
import { ErrorDefs, createBotError } from '../../errors/ErrorCodes';
import { prisma } from '../../database';

export async function handleSetupWizardInteraction(interaction: MessageComponentInteraction, locale: SupportedLocale) {
  const customId = interaction.customId;

  // Validate admin permission
  if (!interaction.memberPermissions?.has(PermissionFlagsBits.Administrator) && !interaction.memberPermissions?.has(PermissionFlagsBits.ManageGuild)) {
    throw createBotError(ErrorDefs.USER_NOT_ADMIN);
  }

  // Handle finishes & expiration
  if (customId === 'setup_finish') {
    await interaction.update({
      content: t(locale, 'commands.setup.finished'),
      embeds: [],
      components: [],
    });
    return;
  }

  // Next/Refresh Button Routing
  if (customId.startsWith('setup_next_') || customId.startsWith('setup_refresh_')) {
    const stepMatch = customId.match(/setup_(next|refresh)_(\d+)/);
    if (!stepMatch) return;
    const targetStep = parseInt(stepMatch[2], 10);

    const { embed, components } = await SetupWizardRenderer.renderStep(targetStep, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }

  // Step 4 Toggle: Audit Category
  if (customId.startsWith('setup_audit_toggle_')) {
    const category = customId.replace('setup_audit_toggle_', '');
    const audit = await prisma.auditChannel.findUnique({ where: { guildId: interaction.guildId! } });
    if (!audit) return;

    let disabled = [...audit.disabledCategories];
    if (disabled.includes(category)) {
      disabled = disabled.filter(c => c !== category);
    } else {
      disabled.push(category);
    }

    await prisma.auditChannel.update({
      where: { guildId: interaction.guildId! },
      data: { disabledCategories: disabled }
    });

    const { embed, components } = await SetupWizardRenderer.renderStep(4, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }

  // Step 1: Language Select
  if (customId === 'setup_lang_select' && interaction.isStringSelectMenu()) {
    const selectedLocale = interaction.values[0] as SupportedLocale;
    await prisma.guildConfig.upsert({
      where: { guildId: interaction.guildId! },
      update: { locale: selectedLocale },
      create: { guildId: interaction.guildId!, locale: selectedLocale }
    });
    
    // Render the next step immediately using the new locale
    const { embed, components } = await SetupWizardRenderer.renderStep(2, interaction, selectedLocale);
    await interaction.update({ embeds: [embed], components });
    return;
  }

  // Step 3: Audit Channel Select / Disable
  if (customId === 'setup_audit_select' && interaction.isChannelSelectMenu()) {
    const channelId = interaction.values[0];
    await prisma.auditChannel.upsert({
      where: { guildId: interaction.guildId! },
      update: { channelId },
      create: { guildId: interaction.guildId!, channelId }
    });
    
    // Auto proceed to next step (Step 4: Categories)
    const { embed, components } = await SetupWizardRenderer.renderStep(4, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }
  if (customId === 'setup_audit_disable') {
    await prisma.auditChannel.delete({ where: { guildId: interaction.guildId! } }).catch(() => {});
    // Skip categories if disabled, go to Step 5: Voice Setup
    const { embed, components } = await SetupWizardRenderer.renderStep(5, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }

  // Step 4: Voice Generator Select / Auto / Disable
  if (customId === 'setup_voice_select' && interaction.isChannelSelectMenu()) {
    const channelId = interaction.values[0];
    
    const channel = await interaction.guild?.channels.fetch(channelId);
    if (!channel || channel.type !== ChannelType.GuildVoice) {
      throw createBotError(ErrorDefs.INVALID_CHANNEL_NAME); // fallback error
    }
    
    // Since channelId is the PK, upsert or deleteMany+create
    const existing = await prisma.voiceGenerator.findFirst({ where: { guildId: interaction.guildId! } });
    if (existing && existing.channelId !== channelId) {
      await prisma.voiceGenerator.delete({ where: { channelId: existing.channelId } }).catch(() => {});
    }
    await prisma.voiceGenerator.upsert({
      where: { channelId: channel.id },
      update: { guildId: interaction.guildId!, categoryId: channel.parentId },
      create: { channelId: channel.id, guildId: interaction.guildId!, categoryId: channel.parentId }
    });
    
    const { embed, components } = await SetupWizardRenderer.renderStep(6, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }
  
  if (customId === 'setup_voice_auto') {
    if (!interaction.guild) return;
    try {
      // Defer update because creating channels takes time
      await interaction.deferUpdate();
      
      const newCategory = await interaction.guild.channels.create({
        name: t(locale, 'commands.setup.defaultCategoryName'),
        type: ChannelType.GuildCategory,
      });

      const newChannel = await interaction.guild.channels.create({
        name: t(locale, 'commands.setup.defaultGeneratorName'),
        type: ChannelType.GuildVoice,
        parent: newCategory.id,
      });

      const existing = await prisma.voiceGenerator.findFirst({ where: { guildId: interaction.guildId! } });
      if (existing) {
        await prisma.voiceGenerator.delete({ where: { channelId: existing.channelId } }).catch(() => {});
      }
      await prisma.voiceGenerator.create({
        data: {
          channelId: newChannel.id,
          guildId: interaction.guildId!,
          categoryId: newCategory.id,
        }
      });
      
      const { embed, components } = await SetupWizardRenderer.renderStep(6, interaction, locale);
      await interaction.editReply({ embeds: [embed], components });
    } catch (e) {
      if ((e as Error).message.includes('Missing Permissions')) {
        throw createBotError(ErrorDefs.BOT_MISSING_MANAGE_CHANNELS, e as Error);
      }
      throw e;
    }
    return;
  }

  if (customId === 'setup_voice_disable') {
    await prisma.voiceGenerator.deleteMany({ where: { guildId: interaction.guildId! } });
    const { embed, components } = await SetupWizardRenderer.renderStep(6, interaction, locale);
    await interaction.update({ embeds: [embed], components });
    return;
  }
}
