const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); const { getServerMode, getEmbedColor, EMBED_COLORS } = require('../utils/modeHelper'); const activeReminders = new Map(); function parseTime(timeStr) { const regex = /^(\d+)(s|m|h|d)$/i; const match = timeStr.match(regex); if (!match) return null; const value = parseInt(match[1]); const unit = match[2].toLowerCase(); const multipliers = { 's': 1000, 'm': 60 * 1000, 'h': 60 * 60 * 1000, 'd': 24 * 60 * 60 * 1000 }; return value * multipliers[unit]; } module.exports = { data: new SlashCommandBuilder() .setName('remind') .setDescription('Set a personal reminder') .addSubcommand(subcommand => subcommand .setName('set') .setDescription('Set a new reminder') .addStringOption(option => option.setName('time') .setDescription('When to remind (e.g., 30m, 2h, 1d)') .setRequired(true) ) .addStringOption(option => option.setName('message') .setDescription('What to remind you about') .setRequired(true) .setMaxLength(500) ) ) .addSubcommand(subcommand => subcommand .setName('list') .setDescription('List your active reminders') ) .addSubcommand(subcommand => subcommand .setName('cancel') .setDescription('Cancel a reminder') .addStringOption(option => option.setName('id') .setDescription('The reminder ID to cancel') .setRequired(true) ) ), async execute(interaction, supabase, client) { const subcommand = interaction.options.getSubcommand(); const mode = await getServerMode(supabase, interaction.guildId); const userId = interaction.user.id; if (subcommand === 'set') { const timeStr = interaction.options.getString('time'); const message = interaction.options.getString('message'); const duration = parseTime(timeStr); if (!duration) { return interaction.reply({ content: 'Invalid time format. Use formats like: 30s, 5m, 2h, 1d', ephemeral: true }); } if (duration < 10000) { return interaction.reply({ content: 'Reminder must be at least 10 seconds in the future.', ephemeral: true }); } if (duration > 30 * 24 * 60 * 60 * 1000) { return interaction.reply({ content: 'Reminder cannot be more than 30 days in the future.', ephemeral: true }); } const reminderId = `${Date.now()}-${Math.random().toString(36).substr(2, 6)}`; const reminderTime = Date.now() + duration; const timeout = setTimeout(async () => { try { const user = await client.users.fetch(userId); const reminderEmbed = new EmbedBuilder() .setColor(EMBED_COLORS.warning) .setTitle('⏰ Reminder!') .setDescription(message) .addFields({ name: '📍 Set', value: `` }) .setTimestamp(); await user.send({ embeds: [reminderEmbed] }); } catch (e) { try { const channel = await client.channels.fetch(interaction.channelId); await channel.send({ content: `<@${userId}> ⏰ **Reminder:** ${message}` }); } catch (e2) {} } const userReminders = activeReminders.get(userId) || []; activeReminders.set(userId, userReminders.filter(r => r.id !== reminderId)); }, duration); const userReminders = activeReminders.get(userId) || []; userReminders.push({ id: reminderId, message, time: reminderTime, timeout, channelId: interaction.channelId }); activeReminders.set(userId, userReminders); const embed = new EmbedBuilder() .setColor(EMBED_COLORS.success) .setTitle('⏰ Reminder Set!') .setDescription(`I'll remind you: **${message}**`) .addFields( { name: '⏱️ In', value: timeStr, inline: true }, { name: '📅 At', value: ``, inline: true }, { name: '🆔 ID', value: `\`${reminderId}\``, inline: true } ) .setTimestamp(); await interaction.reply({ embeds: [embed], ephemeral: true }); } else if (subcommand === 'list') { const userReminders = activeReminders.get(userId) || []; if (userReminders.length === 0) { return interaction.reply({ content: 'You have no active reminders.', ephemeral: true }); } const list = userReminders.map((r, i) => { return `${i + 1}. **${r.message.substring(0, 50)}${r.message.length > 50 ? '...' : ''}**\n ⏰ | ID: \`${r.id}\``; }).join('\n\n'); const embed = new EmbedBuilder() .setColor(getEmbedColor(mode)) .setTitle('⏰ Your Reminders') .setDescription(list) .setFooter({ text: `${userReminders.length} active reminder(s)` }) .setTimestamp(); await interaction.reply({ embeds: [embed], ephemeral: true }); } else if (subcommand === 'cancel') { const reminderId = interaction.options.getString('id'); const userReminders = activeReminders.get(userId) || []; const reminder = userReminders.find(r => r.id === reminderId); if (!reminder) { return interaction.reply({ content: 'Reminder not found. Use `/remind list` to see your reminders.', ephemeral: true }); } clearTimeout(reminder.timeout); activeReminders.set(userId, userReminders.filter(r => r.id !== reminderId)); const embed = new EmbedBuilder() .setColor(EMBED_COLORS.success) .setTitle('🗑️ Reminder Cancelled') .setDescription(`Cancelled reminder: **${reminder.message.substring(0, 100)}**`) .setTimestamp(); await interaction.reply({ embeds: [embed], ephemeral: true }); } }, };