const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
const { invalidateCooldownCache, DEFAULT_COOLDOWNS } = require('../utils/cooldownManager');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('cooldowns')
    .setDescription('Manage command cooldowns for this server')
    .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
    .addSubcommand(sub =>
      sub.setName('set')
        .setDescription('Set a custom cooldown for a command')
        .addStringOption(opt =>
          opt.setName('command')
            .setDescription('The command to set cooldown for')
            .setRequired(true)
            .addChoices(
              { name: 'work', value: 'work' },
              { name: 'daily', value: 'daily' },
              { name: 'slots', value: 'slots' },
              { name: 'coinflip', value: 'coinflip' },
              { name: 'rep', value: 'rep' },
              { name: 'trivia', value: 'trivia' },
              { name: 'heist', value: 'heist' },
              { name: 'duel', value: 'duel' },
              { name: 'gift', value: 'gift' },
              { name: 'trade', value: 'trade' }
            ))
        .addIntegerOption(opt =>
          opt.setName('seconds')
            .setDescription('Cooldown in seconds (0 = no cooldown, -1 = reset to default)')
            .setRequired(true)
            .setMinValue(-1)
            .setMaxValue(604800)))
    .addSubcommand(sub =>
      sub.setName('list')
        .setDescription('View all custom cooldowns for this server'))
    .addSubcommand(sub =>
      sub.setName('reset')
        .setDescription('Reset a command to its default cooldown')
        .addStringOption(opt =>
          opt.setName('command')
            .setDescription('The command to reset (or "all" for all commands)')
            .setRequired(true)
            .addChoices(
              { name: 'work', value: 'work' },
              { name: 'daily', value: 'daily' },
              { name: 'slots', value: 'slots' },
              { name: 'coinflip', value: 'coinflip' },
              { name: 'rep', value: 'rep' },
              { name: 'trivia', value: 'trivia' },
              { name: 'heist', value: 'heist' },
              { name: 'duel', value: 'duel' },
              { name: 'gift', value: 'gift' },
              { name: 'trade', value: 'trade' },
              { name: 'All Commands', value: 'all' }
            ))),

  async execute(interaction, client, supabase) {
    if (!supabase) {
      return interaction.reply({
        content: '❌ Database not configured. Command cooldowns require Supabase.',
        ephemeral: true
      });
    }

    const guildId = interaction.guildId;
    const subcommand = interaction.options.getSubcommand();

    switch (subcommand) {
      case 'set':
        return handleSet(interaction, supabase, guildId);
      case 'list':
        return handleList(interaction, supabase, guildId);
      case 'reset':
        return handleReset(interaction, supabase, guildId);
    }
  },

  DEFAULT_COOLDOWNS
};

async function handleSet(interaction, supabase, guildId) {
  const command = interaction.options.getString('command');
  const seconds = interaction.options.getInteger('seconds');

  try {
    if (seconds === -1) {
      const { error } = await supabase
        .from('command_cooldowns')
        .delete()
        .eq('guild_id', guildId)
        .eq('command_name', command);

      if (error) throw error;

      invalidateCooldownCache(guildId, command);

      return interaction.reply({
        content: `✅ Reset \`/${command}\` to default cooldown (${formatDuration(DEFAULT_COOLDOWNS[command])}).`,
        ephemeral: true
      });
    }

    const { error } = await supabase
      .from('command_cooldowns')
      .upsert({
        guild_id: guildId,
        command_name: command,
        cooldown_seconds: seconds,
        updated_at: new Date().toISOString()
      }, { onConflict: 'guild_id,command_name' });

    if (error) throw error;

    invalidateCooldownCache(guildId, command);

    const message = seconds === 0
      ? `✅ Disabled cooldown for \`/${command}\`.`
      : `✅ Set \`/${command}\` cooldown to **${formatDuration(seconds)}**.`;

    return interaction.reply({ content: message, ephemeral: true });
  } catch (error) {
    console.error('Failed to set cooldown:', error.message);
    return interaction.reply({
      content: '❌ Failed to update cooldown. Please try again.',
      ephemeral: true
    });
  }
}

async function handleList(interaction, supabase, guildId) {
  try {
    const { data: customCooldowns } = await supabase
      .from('command_cooldowns')
      .select('*')
      .eq('guild_id', guildId)
      .order('command_name');

    const customMap = new Map();
    (customCooldowns || []).forEach(c => customMap.set(c.command_name, c.cooldown_seconds));

    const lines = Object.entries(DEFAULT_COOLDOWNS).map(([cmd, defaultSec]) => {
      const customSec = customMap.get(cmd);
      const isCustom = customSec !== undefined;
      const currentSec = isCustom ? customSec : defaultSec;

      if (currentSec === 0) {
        return `⚡ \`/${cmd}\` - **No cooldown** ${isCustom ? '*(custom)*' : ''}`;
      }

      const duration = formatDuration(currentSec);
      const status = isCustom ? `**${duration}** *(custom)*` : `${duration} *(default)*`;
      return `⏱️ \`/${cmd}\` - ${status}`;
    });

    const embed = new EmbedBuilder()
      .setTitle('⏱️ Command Cooldowns')
      .setColor(0x6366f1)
      .setDescription(lines.join('\n'))
      .setFooter({ text: 'Use /cooldowns set to customize' })
      .setTimestamp();

    return interaction.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Failed to list cooldowns:', error.message);
    return interaction.reply({
      content: '❌ Failed to fetch cooldown settings. Please try again.',
      ephemeral: true
    });
  }
}

async function handleReset(interaction, supabase, guildId) {
  const command = interaction.options.getString('command');

  try {
    let query = supabase.from('command_cooldowns').delete().eq('guild_id', guildId);

    if (command !== 'all') {
      query = query.eq('command_name', command);
    }

    const { data, error } = await query.select();

    if (error) throw error;

    if (command === 'all') {
      invalidateCooldownCache(guildId);
    } else {
      invalidateCooldownCache(guildId, command);
    }

    const count = data?.length || 0;

    if (command === 'all') {
      return interaction.reply({
        content: `✅ Reset **${count}** command(s) to their default cooldowns.`,
        ephemeral: true
      });
    }

    if (count === 0) {
      return interaction.reply({
        content: `ℹ️ \`/${command}\` was already using the default cooldown.`,
        ephemeral: true
      });
    }

    return interaction.reply({
      content: `✅ Reset \`/${command}\` to default cooldown (${formatDuration(DEFAULT_COOLDOWNS[command])}).`,
      ephemeral: true
    });
  } catch (error) {
    console.error('Failed to reset cooldown:', error.message);
    return interaction.reply({
      content: '❌ Failed to reset cooldown. Please try again.',
      ephemeral: true
    });
  }
}

function formatDuration(seconds) {
  if (seconds === 0) return 'No cooldown';
  if (seconds < 60) return `${seconds}s`;
  if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
  if (seconds < 86400) {
    const hours = Math.floor(seconds / 3600);
    const mins = Math.floor((seconds % 3600) / 60);
    return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
  }
  const days = Math.floor(seconds / 86400);
  const hours = Math.floor((seconds % 86400) / 3600);
  return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
}
