import type { StringSelectMenuInteraction, ButtonInteraction, MessageFlags } from "discord.js"; import { inventoryService } from "@shared/modules/inventory/inventory.service"; import { getLootboxResultMessage } from "./inventory.view"; import type { ItemUsageData } from "@shared/lib/types"; import { getGuildConfig } from "@shared/lib/config"; import { INVENTORY_CUSTOM_IDS } from "./inventory.types"; export interface InventoryState { ownerId: string; viewerId: string; page: number; selectedItemId: number | null; } /** * Extracts the viewer user ID from an inventory custom ID. * Custom IDs follow the format: inv_{action}_{viewerId} */ export function parseInventoryCustomId(customId: string): { action: string; viewerId: string } | null { const match = customId.match(/^inv_(\w+?)_(\d+)$/); if (!match) return null; return { action: match[1]!, viewerId: match[2]! }; } /** * Checks if a custom ID belongs to the inventory system. */ export function isInventoryInteraction(customId: string): boolean { return customId.startsWith(INVENTORY_CUSTOM_IDS.PREFIX); } /** * Handles the "Use" button — executes item effects. * Returns the result messages array from inventoryService.useItem, * plus handles role-based effects that require the guild member. */ export async function executeItemUse( interaction: ButtonInteraction, userId: string, itemId: number, ): Promise<{ results: any[]; usageData: ItemUsageData | null; item: any }> { const result = await inventoryService.useItem(userId, itemId); // Handle role effects (same logic as /use command) const usageData = result.usageData; if (usageData) { const guildConfig = await getGuildConfig(interaction.guildId!); const colorRoles = guildConfig.colorRoles ?? []; for (const effect of usageData.effects) { if (effect.type === "TEMP_ROLE" || effect.type === "COLOR_ROLE") { try { const member = await interaction.guild?.members.fetch(userId); if (member) { if (effect.type === "TEMP_ROLE") { await member.roles.add(effect.roleId); } else if (effect.type === "COLOR_ROLE") { const rolesToRemove = colorRoles.filter((r: string) => member.roles.cache.has(r)); if (rolesToRemove.length > 0) await member.roles.remove(rolesToRemove); await member.roles.add(effect.roleId); } } } catch (e) { console.error("Failed to assign role in inventory use:", e); result.results.push("⚠️ Failed to assign role (Check bot permissions)"); } } } } return result; }