const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('bulkmod')
    .setDescription('Perform moderation actions on multiple users at once')
    .setDefaultMemberPermissions(PermissionFlagsBits.ModerateMembers)
    .addSubcommand(sub =>
      sub.setName('ban')
        .setDescription('Ban multiple users at once')
        .addStringOption(opt =>
          opt.setName('users')
            .setDescription('User IDs or mentions separated by spaces')
            .setRequired(true))
        .addStringOption(opt =>
          opt.setName('reason')
            .setDescription('Reason for ban')
            .setRequired(false)
            .setMaxLength(500))
        .addIntegerOption(opt =>
          opt.setName('delete_days')
            .setDescription('Days of messages to delete (0-7)')
            .setMinValue(0)
            .setMaxValue(7)))
    .addSubcommand(sub =>
      sub.setName('kick')
        .setDescription('Kick multiple users at once')
        .addStringOption(opt =>
          opt.setName('users')
            .setDescription('User IDs or mentions separated by spaces')
            .setRequired(true))
        .addStringOption(opt =>
          opt.setName('reason')
            .setDescription('Reason for kick')
            .setRequired(false)
            .setMaxLength(500)))
    .addSubcommand(sub =>
      sub.setName('timeout')
        .setDescription('Timeout multiple users at once')
        .addStringOption(opt =>
          opt.setName('users')
            .setDescription('User IDs or mentions separated by spaces')
            .setRequired(true))
        .addStringOption(opt =>
          opt.setName('duration')
            .setDescription('Timeout duration')
            .setRequired(true)
            .addChoices(
              { name: '5 minutes', value: '5m' },
              { name: '10 minutes', value: '10m' },
              { name: '30 minutes', value: '30m' },
              { name: '1 hour', value: '1h' },
              { name: '6 hours', value: '6h' },
              { name: '12 hours', value: '12h' },
              { name: '1 day', value: '1d' },
              { name: '3 days', value: '3d' },
              { name: '1 week', value: '1w' }
            ))
        .addStringOption(opt =>
          opt.setName('reason')
            .setDescription('Reason for timeout')
            .setRequired(false)
            .setMaxLength(500)))
    .addSubcommand(sub =>
      sub.setName('warn')
        .setDescription('Warn multiple users at once')
        .addStringOption(opt =>
          opt.setName('users')
            .setDescription('User IDs or mentions separated by spaces')
            .setRequired(true))
        .addStringOption(opt =>
          opt.setName('reason')
            .setDescription('Reason for warning')
            .setRequired(true)
            .setMaxLength(500)))
    .addSubcommand(sub =>
      sub.setName('remove_timeout')
        .setDescription('Remove timeout from multiple users')
        .addStringOption(opt =>
          opt.setName('users')
            .setDescription('User IDs or mentions separated by spaces')
            .setRequired(true))),

  async execute(interaction, supabase, client) {
    await interaction.deferReply();

    const subcommand = interaction.options.getSubcommand();
    const usersInput = interaction.options.getString('users');
    const reason = interaction.options.getString('reason') || 'No reason provided';
    const moderator = interaction.user;
    
    const userIds = parseUserIds(usersInput);
    
    if (userIds.length === 0) {
      return interaction.editReply({ content: '❌ No valid user IDs provided.' });
    }
    
    if (userIds.length > 25) {
      return interaction.editReply({ content: '❌ Maximum 25 users per bulk action.' });
    }

    const results = { success: [], failed: [] };

    switch (subcommand) {
      case 'ban':
        await handleBulkBan(interaction, userIds, reason, results, supabase, moderator);
        break;
      case 'kick':
        await handleBulkKick(interaction, userIds, reason, results, supabase, moderator);
        break;
      case 'timeout':
        const duration = interaction.options.getString('duration');
        await handleBulkTimeout(interaction, userIds, duration, reason, results, supabase, moderator);
        break;
      case 'warn':
        await handleBulkWarn(interaction, userIds, reason, results, supabase, moderator);
        break;
      case 'remove_timeout':
        await handleBulkRemoveTimeout(interaction, userIds, results, supabase, moderator);
        break;
    }

    const embed = createResultEmbed(subcommand, results, moderator);
    await interaction.editReply({ embeds: [embed] });
  },
};

function parseUserIds(input) {
  const mentionRegex = /<@!?(\d+)>/g;
  const idRegex = /\b(\d{17,20})\b/g;
  
  const ids = new Set();
  
  let match;
  while ((match = mentionRegex.exec(input)) !== null) {
    ids.add(match[1]);
  }
  while ((match = idRegex.exec(input)) !== null) {
    ids.add(match[1]);
  }
  
  return Array.from(ids);
}

function parseDuration(duration) {
  const units = { m: 60, h: 3600, d: 86400, w: 604800 };
  const match = duration.match(/^(\d+)([mhdw])$/);
  if (!match) return null;
  return parseInt(match[1]) * units[match[2]] * 1000;
}

async function handleBulkBan(interaction, userIds, reason, results, supabase, moderator) {
  const deleteDays = interaction.options.getInteger('delete_days') || 0;
  
  for (const userId of userIds) {
    try {
      if (userId === moderator.id) {
        results.failed.push({ id: userId, reason: 'Cannot ban yourself' });
        continue;
      }

      const member = await interaction.guild.members.fetch(userId).catch(() => null);
      if (member && !member.bannable) {
        results.failed.push({ id: userId, reason: 'Not bannable' });
        continue;
      }

      await interaction.guild.members.ban(userId, {
        reason: `[Bulk] ${reason} | By ${moderator.tag}`,
        deleteMessageSeconds: deleteDays * 24 * 60 * 60
      });

      if (supabase) {
        const user = await interaction.client.users.fetch(userId).catch(() => null);
        await supabase.from('mod_actions').insert({
          guild_id: interaction.guildId,
          action: 'ban',
          user_id: userId,
          user_tag: user?.tag || 'Unknown',
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: `[Bulk] ${reason}`,
        }).catch(() => {});
      }

      results.success.push(userId);
    } catch (error) {
      results.failed.push({ id: userId, reason: error.message.substring(0, 50) });
    }
  }
}

async function handleBulkKick(interaction, userIds, reason, results, supabase, moderator) {
  for (const userId of userIds) {
    try {
      if (userId === moderator.id) {
        results.failed.push({ id: userId, reason: 'Cannot kick yourself' });
        continue;
      }

      const member = await interaction.guild.members.fetch(userId).catch(() => null);
      if (!member) {
        results.failed.push({ id: userId, reason: 'Not in server' });
        continue;
      }
      if (!member.kickable) {
        results.failed.push({ id: userId, reason: 'Not kickable' });
        continue;
      }

      await member.kick(`[Bulk] ${reason} | By ${moderator.tag}`);

      if (supabase) {
        await supabase.from('mod_actions').insert({
          guild_id: interaction.guildId,
          action: 'kick',
          user_id: userId,
          user_tag: member.user.tag,
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: `[Bulk] ${reason}`,
        }).catch(() => {});
      }

      results.success.push(userId);
    } catch (error) {
      results.failed.push({ id: userId, reason: error.message.substring(0, 50) });
    }
  }
}

async function handleBulkTimeout(interaction, userIds, duration, reason, results, supabase, moderator) {
  const durationMs = parseDuration(duration);
  
  for (const userId of userIds) {
    try {
      if (userId === moderator.id) {
        results.failed.push({ id: userId, reason: 'Cannot timeout yourself' });
        continue;
      }

      const member = await interaction.guild.members.fetch(userId).catch(() => null);
      if (!member) {
        results.failed.push({ id: userId, reason: 'Not in server' });
        continue;
      }
      if (!member.moderatable) {
        results.failed.push({ id: userId, reason: 'Not moderatable' });
        continue;
      }

      await member.timeout(durationMs, `[Bulk] ${reason} | By ${moderator.tag}`);

      if (supabase) {
        await supabase.from('mod_actions').insert({
          guild_id: interaction.guildId,
          action: 'timeout',
          user_id: userId,
          user_tag: member.user.tag,
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: `[Bulk] ${reason}`,
          duration: duration
        }).catch(() => {});
      }

      results.success.push(userId);
    } catch (error) {
      results.failed.push({ id: userId, reason: error.message.substring(0, 50) });
    }
  }
}

async function handleBulkWarn(interaction, userIds, reason, results, supabase, moderator) {
  for (const userId of userIds) {
    try {
      const member = await interaction.guild.members.fetch(userId).catch(() => null);
      if (!member) {
        results.failed.push({ id: userId, reason: 'Not in server' });
        continue;
      }

      if (supabase) {
        await supabase.from('warnings').insert({
          guild_id: interaction.guildId,
          user_id: userId,
          user_tag: member.user.tag,
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: `[Bulk] ${reason}`,
        });

        await supabase.from('mod_actions').insert({
          guild_id: interaction.guildId,
          action: 'warn',
          user_id: userId,
          user_tag: member.user.tag,
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: `[Bulk] ${reason}`,
        }).catch(() => {});
      }

      try {
        await member.user.send({
          embeds: [
            new EmbedBuilder()
              .setColor(0xffa500)
              .setTitle(`Warning from ${interaction.guild.name}`)
              .setDescription(reason)
              .setTimestamp()
          ]
        });
      } catch {}

      results.success.push(userId);
    } catch (error) {
      results.failed.push({ id: userId, reason: error.message.substring(0, 50) });
    }
  }
}

async function handleBulkRemoveTimeout(interaction, userIds, results, supabase, moderator) {
  for (const userId of userIds) {
    try {
      const member = await interaction.guild.members.fetch(userId).catch(() => null);
      if (!member) {
        results.failed.push({ id: userId, reason: 'Not in server' });
        continue;
      }
      if (!member.isCommunicationDisabled()) {
        results.failed.push({ id: userId, reason: 'Not timed out' });
        continue;
      }

      await member.timeout(null, `Timeout removed by ${moderator.tag}`);

      if (supabase) {
        await supabase.from('mod_actions').insert({
          guild_id: interaction.guildId,
          action: 'untimeout',
          user_id: userId,
          user_tag: member.user.tag,
          moderator_id: moderator.id,
          moderator_tag: moderator.tag,
          reason: 'Bulk timeout removal',
        }).catch(() => {});
      }

      results.success.push(userId);
    } catch (error) {
      results.failed.push({ id: userId, reason: error.message.substring(0, 50) });
    }
  }
}

function createResultEmbed(action, results, moderator) {
  const actionNames = {
    ban: 'Bulk Ban',
    kick: 'Bulk Kick',
    timeout: 'Bulk Timeout',
    warn: 'Bulk Warning',
    remove_timeout: 'Bulk Timeout Removal'
  };
  
  const colors = {
    ban: 0xff0000,
    kick: 0xff6b6b,
    timeout: 0xffa500,
    warn: 0xffcc00,
    remove_timeout: 0x00ff00
  };

  const embed = new EmbedBuilder()
    .setTitle(`${actionNames[action]} Results`)
    .setColor(colors[action])
    .setTimestamp()
    .setFooter({ text: `Action by ${moderator.tag}` });

  if (results.success.length > 0) {
    const successList = results.success.map(id => `<@${id}>`).join(', ');
    embed.addFields({ 
      name: `✅ Successful (${results.success.length})`, 
      value: successList.length > 1024 ? `${results.success.length} users affected` : successList 
    });
  }

  if (results.failed.length > 0) {
    const failedList = results.failed.map(f => `<@${f.id}>: ${f.reason}`).join('\n');
    embed.addFields({ 
      name: `❌ Failed (${results.failed.length})`, 
      value: failedList.length > 1024 ? `${results.failed.length} users failed` : failedList 
    });
  }

  if (results.success.length === 0 && results.failed.length === 0) {
    embed.setDescription('No users were processed.');
  }

  return embed;
}
