import { createCommand } from "@/lib/utils"; import { SlashCommandBuilder, EmbedBuilder, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle, ThreadAutoArchiveDuration } from "discord.js"; import { TradeService } from "@/modules/trade/trade.service"; import { updateTradeDashboard } from "@/modules/trade/trade.interaction"; import { createErrorEmbed, createWarningEmbed } from "@lib/embeds"; export const trade = createCommand({ data: new SlashCommandBuilder() .setName("trade") .setDescription("Start a trade with another player") .addUserOption(option => option.setName("user") .setDescription("The user to trade with") .setRequired(true) ), execute: async (interaction) => { const targetUser = interaction.options.getUser("user", true); if (targetUser.id === interaction.user.id) { await interaction.reply({ embeds: [createWarningEmbed("You cannot trade with yourself.")], ephemeral: true }); return; } if (targetUser.bot) { await interaction.reply({ embeds: [createWarningEmbed("You cannot trade with bots.")], ephemeral: true }); return; } // Create Thread const channel = interaction.channel; if (!channel || channel.type === ChannelType.DM) { await interaction.reply({ embeds: [createErrorEmbed("Cannot start trade in DMs.")], ephemeral: true }); return; } // Check if we can create threads // Assuming permissions are fine. await interaction.reply({ content: `🔄 Setting up trade with ${targetUser}...` }); const message = await interaction.fetchReply(); let thread; try { thread = await message.startThread({ name: `trade-${interaction.user.username}-${targetUser.username}`, autoArchiveDuration: ThreadAutoArchiveDuration.OneHour, reason: "Trading Session" }); } catch (e) { // Fallback if message threads fail, try channel threads (private preferred) // But startThread on message is usually easiest. await interaction.editReply({ content: "", embeds: [createErrorEmbed("Failed to create trade thread. Check permissions.")] }); return; } // Setup Session TradeService.createSession(thread.id, { id: interaction.user.id, username: interaction.user.username }, { id: targetUser.id, username: targetUser.username } ); // Send Dashboard to Thread const embed = new EmbedBuilder() .setTitle("🤝 Trading Session") .setDescription(`Trade started between ${interaction.user} and ${targetUser}.\nUse the controls below to build your offer.`) .setColor(0xFFD700) .addFields( { name: interaction.user.username, value: "*Empty Offer*", inline: true }, { name: targetUser.username, value: "*Empty Offer*", inline: true } ) .setFooter({ text: "Both parties must click Lock to confirm trade." }); const row = new ActionRowBuilder() .addComponents( new ButtonBuilder().setCustomId('trade_add_item').setLabel('Add Item').setStyle(ButtonStyle.Secondary), new ButtonBuilder().setCustomId('trade_add_money').setLabel('Add Money').setStyle(ButtonStyle.Success), new ButtonBuilder().setCustomId('trade_remove_item').setLabel('Remove Item').setStyle(ButtonStyle.Secondary), new ButtonBuilder().setCustomId('trade_lock').setLabel('Lock / Unlock').setStyle(ButtonStyle.Primary), new ButtonBuilder().setCustomId('trade_cancel').setLabel('Cancel').setStyle(ButtonStyle.Danger), ); await thread.send({ content: `${interaction.user} ${targetUser} Welcome to your trading session!`, embeds: [embed], components: [row] }); // Update original reply await interaction.editReply({ content: `✅ Trade opened: <#${thread.id}>` }); } });