import BotCommand from "../../libs/BotCommand"; import BotClient from "../../libs/BotClient"; import { ChatInputCommandInteraction, MessageFlags, EmbedBuilder, PermissionFlagsBits } from "discord.js"; import Team from "../../models/Team"; import User from "../../models/User"; import Database from "../../libs/Database"; import PointsManager from "../../libs/PointsManager"; export default class TeamManageCommand extends BotCommand { constructor() { super("team", "Create, edit, or delete teams (Admin only)", "/team"); this.data.addSubcommand(subcommand => subcommand.setName("create") .setDescription("Create a new team") .addStringOption(option => option.setName("name") .setDescription("Team name") .setRequired(true)) .addUserOption(option => option.setName("leader") .setDescription("Team leader") .setRequired(true)) .addRoleOption(option => option.setName("role") .setDescription("Team role to assign to members") .setRequired(true)) .addStringOption(option => option.setName("description") .setDescription("Team description") .setRequired(false)) ); this.data.addSubcommand(subcommand => subcommand.setName("delete") .setDescription("Delete a team") .addStringOption(option => option.setName("name") .setDescription("Team name") .setRequired(true)) ); this.data.addSubcommand(subcommand => subcommand.setName("change-leader") .setDescription("Change team leader") .addStringOption(option => option.setName("name") .setDescription("Team name") .setRequired(true)) .addUserOption(option => option.setName("new-leader") .setDescription("New team leader") .setRequired(true)) ); this.data.addSubcommand(subcommand => subcommand.setName("list") .setDescription("List all teams") ); this.data.addSubcommand(subcommand => subcommand.setName("change-user-team") .setDescription("Change a user's team (only during first week of month)") .addUserOption(option => option.setName("user") .setDescription("User to move") .setRequired(true)) .addStringOption(option => option.setName("team") .setDescription("Team name") .setRequired(true)) ); this.data.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild); } override async execute(Discord: any, client: BotClient, interaction: ChatInputCommandInteraction): Promise { const db = Database.getInstance(); if (!db.isConnected()) { return interaction.reply({ content: "❌ Database not connected. Points system unavailable.", flags: MessageFlags.Ephemeral }); } const subcommand = interaction.options.getSubcommand(); try { if (subcommand === "create") { const name = interaction.options.getString("name", true); const leader = interaction.options.getUser("leader", true); const role = interaction.options.getRole("role", true); const description = interaction.options.getString("description") || ""; const existing = await Team.findOne({ name }); if (existing) { return interaction.reply({ content: `❌ Team **${name}** already exists.`, flags: MessageFlags.Ephemeral }); } const team = new Team({ name, leaderId: leader.id, roleId: role.id, description, points: 0, memberCount: 0 }); await team.save(); const embed = new EmbedBuilder() .setTitle("✅ Team Created") .setColor(0x22c55e) .addFields( { name: "Team Name", value: name, inline: true }, { name: "Leader", value: `<@${leader.id}>`, inline: true }, { name: "Role", value: `<@&${role.id}>`, inline: true }, { name: "Description", value: description || "None", inline: false } ) .setTimestamp(); return interaction.reply({ embeds: [embed] }); } else if (subcommand === "delete") { const name = interaction.options.getString("name", true); const team = await Team.findOne({ name }); if (!team) { return interaction.reply({ content: `❌ Team **${name}** not found.`, flags: MessageFlags.Ephemeral }); } // Remove role from all team members const teamMembers = await User.find({ teamId: team._id }); const guild = interaction.guild; if (guild) { for (const user of teamMembers) { try { const member = await guild.members.fetch(user.userId); if (member && member.roles.cache.has(team.roleId)) { await member.roles.remove(team.roleId); } } catch (err) { console.error(`Failed to remove role from ${user.userId}:`, err); } } } await User.updateMany({ teamId: team._id }, { $set: { teamId: null } }); await Team.deleteOne({ _id: team._id }); return interaction.reply({ content: `✅ Team **${name}** has been deleted and roles removed from members.`, flags: MessageFlags.Ephemeral }); } else if (subcommand === "change-leader") { const name = interaction.options.getString("name", true); const newLeader = interaction.options.getUser("new-leader", true); const team = await Team.findOne({ name }); if (!team) { return interaction.reply({ content: `❌ Team **${name}** not found.`, flags: MessageFlags.Ephemeral }); } team.leaderId = newLeader.id; await team.save(); return interaction.reply({ content: `✅ Team **${name}** leader changed to <@${newLeader.id}>.`, flags: MessageFlags.Ephemeral }); } else if (subcommand === "list") { const teams = await Team.find().sort({ points: -1 }).exec(); if (teams.length === 0) { return interaction.reply({ content: "No teams exist yet.", flags: MessageFlags.Ephemeral }); } const embed = new EmbedBuilder() .setTitle("📋 All Teams") .setColor(0x60a5fa) .setDescription(teams.map((t: any, i: number) => `**${i + 1}.** ${t.name} - Leader: <@${t.leaderId}> - Role: <@&${t.roleId}>\n` + ` Members: ${t.memberCount} | Points: ${t.points} (Adjusted: ${t.adjustedPoints})` ).join("\n\n")) .setTimestamp(); return interaction.reply({ embeds: [embed] }); } else if (subcommand === "change-user-team") { const user = interaction.options.getUser("user", true); const teamName = interaction.options.getString("team", true); const team = await Team.findOne({ name: teamName }); if (!team) { return interaction.reply({ content: `❌ Team **${teamName}** not found.`, flags: MessageFlags.Ephemeral }); } const result = await PointsManager.joinTeam(user.id, user.username, team._id.toString(), true, interaction.guild || undefined); if (result.success) { return interaction.reply({ content: `✅ <@${user.id}> has been moved to team **${teamName}**.`, flags: MessageFlags.Ephemeral }); } else { return interaction.reply({ content: `❌ ${result.message}`, flags: MessageFlags.Ephemeral }); } } } catch (error) { console.error("Error in team-manage command:", error); return interaction.reply({ content: "❌ An error occurred.", flags: MessageFlags.Ephemeral }); } } }