const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, ChannelType } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('config') .setDescription('Configure server settings') .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addSubcommand(sub => sub.setName('view') .setDescription('View current server configuration') ) .addSubcommand(sub => sub.setName('welcome') .setDescription('Set the welcome channel') .addChannelOption(opt => opt.setName('channel') .setDescription('Channel for welcome messages') .addChannelTypes(ChannelType.GuildText) .setRequired(true) ) ) .addSubcommand(sub => sub.setName('goodbye') .setDescription('Set the goodbye channel') .addChannelOption(opt => opt.setName('channel') .setDescription('Channel for goodbye messages') .addChannelTypes(ChannelType.GuildText) .setRequired(true) ) ) .addSubcommand(sub => sub.setName('modlog') .setDescription('Set the moderation log channel') .addChannelOption(opt => opt.setName('channel') .setDescription('Channel for mod logs') .addChannelTypes(ChannelType.GuildText) .setRequired(true) ) ) .addSubcommand(sub => sub.setName('levelup') .setDescription('Set the level-up announcement channel') .addChannelOption(opt => opt.setName('channel') .setDescription('Channel for level-up messages') .addChannelTypes(ChannelType.GuildText) .setRequired(true) ) ) .addSubcommand(sub => sub.setName('autorole') .setDescription('Set auto-role for new members') .addRoleOption(opt => opt.setName('role') .setDescription('Role to assign on join') .setRequired(true) ) ) .addSubcommand(sub => sub.setName('levelrole') .setDescription('Add a role reward for reaching a level') .addRoleOption(opt => opt.setName('role') .setDescription('Role to give') .setRequired(true) ) .addIntegerOption(opt => opt.setName('level') .setDescription('Level required') .setRequired(true) .setMinValue(1) .setMaxValue(100) ) ), async execute(interaction, supabase, client) { if (!supabase) { return interaction.reply({ content: 'Database not configured.', ephemeral: true }); } const subcommand = interaction.options.getSubcommand(); await interaction.deferReply({ ephemeral: true }); try { if (subcommand === 'view') { const { data: config } = await supabase .from('server_config') .select('*') .eq('guild_id', interaction.guildId) .single(); const embed = new EmbedBuilder() .setColor(0x7c3aed) .setTitle('Server Configuration') .addFields( { name: 'Welcome Channel', value: config?.welcome_channel ? `<#${config.welcome_channel}>` : 'Not set', inline: true }, { name: 'Goodbye Channel', value: config?.goodbye_channel ? `<#${config.goodbye_channel}>` : 'Not set', inline: true }, { name: 'Mod Log Channel', value: config?.modlog_channel ? `<#${config.modlog_channel}>` : 'Not set', inline: true }, { name: 'Level-Up Channel', value: config?.level_up_channel ? `<#${config.level_up_channel}>` : 'Not set', inline: true }, { name: 'Auto Role', value: config?.auto_role ? `<@&${config.auto_role}>` : 'Not set', inline: true } ) .setTimestamp(); const { data: levelRoles } = await supabase .from('level_roles') .select('role_id, level_required') .eq('guild_id', interaction.guildId) .order('level_required', { ascending: true }); if (levelRoles && levelRoles.length > 0) { const roleText = levelRoles.map(lr => `Level ${lr.level_required}: <@&${lr.role_id}>`).join('\n'); embed.addFields({ name: 'Level Roles', value: roleText }); } return interaction.editReply({ embeds: [embed] }); } const updateField = { welcome: 'welcome_channel', goodbye: 'goodbye_channel', modlog: 'modlog_channel', levelup: 'level_up_channel', autorole: 'auto_role', }; if (subcommand === 'levelrole') { const role = interaction.options.getRole('role'); const level = interaction.options.getInteger('level'); await supabase.from('level_roles').upsert({ guild_id: interaction.guildId, role_id: role.id, level_required: level, }, { onConflict: 'guild_id,role_id' }); if (!client.serverConfigs) client.serverConfigs = new Map(); return interaction.editReply({ embeds: [ new EmbedBuilder() .setColor(0x00ff00) .setDescription(`${role} will now be given at level ${level}!`) ] }); } const fieldName = updateField[subcommand]; let value; if (subcommand === 'autorole') { value = interaction.options.getRole('role').id; } else { value = interaction.options.getChannel('channel').id; } await supabase.from('server_config').upsert({ guild_id: interaction.guildId, [fieldName]: value, updated_at: new Date().toISOString(), }, { onConflict: 'guild_id' }); if (!client.serverConfigs) client.serverConfigs = new Map(); const current = client.serverConfigs.get(interaction.guildId) || {}; current[fieldName] = value; client.serverConfigs.set(interaction.guildId, current); const displayValue = subcommand === 'autorole' ? `<@&${value}>` : `<#${value}>`; await interaction.editReply({ embeds: [ new EmbedBuilder() .setColor(0x00ff00) .setDescription(`${subcommand.charAt(0).toUpperCase() + subcommand.slice(1)} set to ${displayValue}!`) ] }); } catch (error) { console.error('Config error:', error); await interaction.editReply({ content: 'Failed to update configuration.' }); } }, };