/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.content.command;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.LongArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.util.FakePlayerFactory;
import net.minecraftforge.event.RegisterCommandsEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.eroticdungeongame.api.workspace.Services;
import top.r3944realms.eroticdungeongame.content.block.ISeatBlock;
import top.r3944realms.eroticdungeongame.content.block.blockentity.BaseSeatBlockEntity;
import top.r3944realms.eroticdungeongame.content.entity.SeatEntity;
import top.r3944realms.eroticdungeongame.content.item.DeviceKeyItem;
import top.r3944realms.eroticdungeongame.content.item.FilterItem;
import top.r3944realms.eroticdungeongame.content.util.FurnitureHelper;
import top.r3944realms.eroticdungeongame.core.service.SeatService;
import top.r3944realms.lib39.core.command.ICommandHelpManager;
import top.r3944realms.lib39.core.command.SimpleHelpCommand;
import top.r3944realms.lib39.util.command.CommandAliasHelper;

import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

public class EDGCommand extends SimpleHelpCommand {
    public EDGCommand(@NotNull RegisterCommandsEvent event) {
        super(event);
        registerCommands(event.getDispatcher());
    }

    @Override
    public ICommandHelpManager getCommandHelpManager() {
        return EDGCommandHelperManager.INSTANCE;
    }

    private static final SuggestionProvider<CommandSourceStack> FILTER_MODE_SUGGESTIONS = (context, builder) -> {
        builder.suggest("whitelist", Component.translatable("filter.eroticdungeongame.mode.whitelist"))
                .suggest("blacklist", Component.literal("filter.eroticdungeongame.mode.blacklist"));
        return builder.buildFuture();
    };

    private static final SuggestionProvider<CommandSourceStack> GAME_MODE_SUGGESTIONS = (context, builder) -> {
        Arrays.stream(FilterItem.GameMode.values())
                .map(FilterItem.GameMode::getName)
                .forEach(builder::suggest);
        return builder.buildFuture();
    };

    private void registerCommands(@NotNull CommandDispatcher<CommandSourceStack> dispatcher) {
        // edg eroticdungeongame
        // edg help toggle <hash>
        // edg device bind <pos> [player] [code] 将[player] (没有则命令执行者) 绑定在<pos>处的设备上 (如果有[code] 则顺便上锁)
        //            unbind <pos> 解绑<pos>处的设备
        //                   [player] 解绑<player> (没有则命令执行者)
        //            lock <pos> [code] 给<pos>上锁 (没有[code]则随机生成一个)
        //                 [player] [code] 给[player] (没有则命令执行者) 所处的设备上锁 (没有[code]则随机生成一个)
        //            unlock <pos> 给<pos>解锁
        //                   [player] 给[player] (没有则命令执行者) 所处的设备解锁
        //     key lock set [code] 给命令执行者手上的钥匙设置<code> (没有[code]则随机生成一个)
        //              get 获取命令执行者手上的钥匙 code
        //              clear 清除命令执行者手上的钥匙 code
        //     filter mode [whitelist/blacklist] 设置过滤器模式，缺省为白名单
        //            gamemode add <gamemode> 添加游戏模式，只能生存/创造/冒险
        //                     remove [gamemode] 移除添加游戏模式，缺省全移除
        //            team add <team> 添加队伍
        //                 remove [team] 移除队伍，缺省全移除
        //            tag add <tag> 添加标签
        //                remove [tag] 移除标签，缺省全移除
        //            workpos set [pos] 设置工作点，缺省则玩家位置
        //                    remove 移除工作点
        //            whitelist add <player> 添加白名单
        //                      remove <player> 移除白名单
        //            blacklist add <player> 添加黑名单
        //                      remove <player> 移除黑名单
        //            info 查看信息
        //            reset 重置
        getRoot()
                .executes(this::handleHelp)
                .then(
                        Commands.literal("device")
                                .requires(source -> source.hasPermission(2))
                                .then(
                                        Commands.literal("bind")
                                                .then(
                                                        Commands.argument("pos", BlockPosArgument.blockPos())
                                                                .executes(this::edg$device$bind$pos$self)
                                                                .then(
                                                                        Commands.argument("player", EntityArgument.player())
                                                                                .executes(this::edg$device$bind$pos$player)
                                                                                .then(
                                                                                        Commands.argument("code", LongArgumentType.longArg())
                                                                                                .executes(this::edg$device$bind$pos$player$code)
                                                                                )
                                                                )
                                                                .then(
                                                                        Commands.argument("code", LongArgumentType.longArg())
                                                                                .executes(this::edg$device$bind$pos$code$self)
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("unbind")
                                                .executes(this::edg$device$unbind$self)
                                                .then(
                                                        Commands.argument("pos", BlockPosArgument.blockPos())
                                                                .executes(this::edg$device$unbind$pos)
                                                )
                                                .then(
                                                        Commands.argument("player", EntityArgument.player())
                                                                .executes(this::edg$device$unbind$player)
                                                )
                                )
                                .then(
                                        Commands.literal("lock")
                                                .executes(this::edg$device$lock$self)
                                                .then(
                                                        Commands.argument("pos", BlockPosArgument.blockPos())
                                                                .executes(this::edg$device$lock$pos)
                                                                .then(
                                                                        Commands.argument("code", LongArgumentType.longArg())
                                                                                .executes(this::edg$device$lock$pos$code)
                                                                )
                                                )
                                                .then(
                                                        Commands.argument("player", EntityArgument.player())
                                                                .executes(this::edg$device$lock$player)
                                                                .then(
                                                                        Commands.argument("code", LongArgumentType.longArg())
                                                                                .executes(this::edg$device$lock$player$code)
                                                                )
                                                )

                                )
                                .then(
                                        Commands.literal("unlock")
                                                .executes(this::edg$device$unlock$self)
                                                .then(
                                                        Commands.argument("pos", BlockPosArgument.blockPos())
                                                                .executes(this::edg$device$unlock$pos)
                                                )
                                                .then(
                                                        Commands.argument("player", EntityArgument.player())
                                                                .executes(this::edg$device$unlock$player)
                                                )
                                )
                )
                .then(
                        Commands.literal("key")
                                .then(
                                        Commands.literal("lock")
                                                .then(
                                                        Commands.literal("set")
                                                                .requires(source -> source.hasPermission(2))
                                                                .executes(this::edg$key$lock$set)
                                                                .then(
                                                                        Commands.argument("code", LongArgumentType.longArg())
                                                                                .executes(this::edg$key$lock$set$code)
                                                                )

                                                ).then(
                                                        Commands.literal("clear")
                                                                .executes(this::edg$key$lock$clear)
                                                ).then(
                                                        Commands.literal("get")
                                                                .executes(this::edg$key$lock$get)
                                                )
                                )
                )
                .then(
                        Commands.literal("filter")
                                .then(
                                        Commands.literal("mode")
                                                .executes(context -> setFilterMode(context, "whitelist"))
                                                .then(
                                                        Commands.argument("mode", StringArgumentType.word())
                                                                .suggests(FILTER_MODE_SUGGESTIONS)
                                                                .executes(context -> setFilterMode(context, StringArgumentType.getString(context, "mode")))
                                                )
                                )
                                .then(
                                        Commands.literal("gamemode")
                                                .then(
                                                        Commands.literal("add")
                                                                .then(
                                                                        Commands.argument("gamemode", StringArgumentType.word())
                                                                                .suggests(GAME_MODE_SUGGESTIONS)
                                                                                .executes(context -> addGameMode(context, StringArgumentType.getString(context, "gamemode")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::clearGameModes)
                                                                .then(
                                                                        Commands.argument("gamemode", StringArgumentType.word())
                                                                                .suggests(GAME_MODE_SUGGESTIONS)
                                                                                .executes(context -> removeGameMode(context, StringArgumentType.getString(context, "gamemode")))
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("tag")
                                                .then(
                                                        Commands.literal("add")
                                                                .then(
                                                                        Commands.argument("tag", StringArgumentType.string())
                                                                                .executes(context -> addTag(context, StringArgumentType.getString(context, "tag")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::clearTags)
                                                                .then(
                                                                        Commands.argument("tag", StringArgumentType.string())
                                                                                .executes(context -> removeTag(context, StringArgumentType.getString(context, "tag")))
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("team")
                                                .then(
                                                        Commands.literal("add")
                                                                .then(
                                                                        Commands.argument("team", StringArgumentType.string())
                                                                                .executes(context -> addTeam(context, StringArgumentType.getString(context, "team")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::clearTeams)
                                                                .then(
                                                                        Commands.argument("team", StringArgumentType.string())
                                                                                .executes(context -> removeTeam(context, StringArgumentType.getString(context, "team")))
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("workpos")
                                                .then(
                                                        Commands.literal("set")
                                                                .executes(context -> setWorkPosition(context, context.getSource().getPlayerOrException().blockPosition()))
                                                                .then(
                                                                        Commands.argument("pos", BlockPosArgument.blockPos())
                                                                                .executes(context -> setWorkPosition(context, BlockPosArgument.getLoadedBlockPos(context, "pos")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::removeWorkPosition)
                                                )
                                )
                                .then(
                                        Commands.literal("whitelist")
                                                .then(
                                                        Commands.literal("add")
                                                                .then(
                                                                        Commands.argument("player", EntityArgument.player())
                                                                                .executes(context -> addWhitelistPlayer(context, EntityArgument.getPlayer(context, "player")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::clearWhitelist)
                                                                .then(
                                                                        Commands.argument("player", EntityArgument.player())
                                                                                .executes(context -> removeWhitelistPlayer(context, EntityArgument.getPlayer(context, "player")))
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("blacklist")
                                                .then(
                                                        Commands.literal("add")
                                                                .then(
                                                                        Commands.argument("player", EntityArgument.player())
                                                                                .executes(context -> addBlacklistPlayer(context, EntityArgument.getPlayer(context, "player")))
                                                                )
                                                )
                                                .then(
                                                        Commands.literal("remove")
                                                                .executes(EDGCommand::clearBlacklist)
                                                                .then(
                                                                        Commands.argument("player", EntityArgument.player())
                                                                                .executes(context -> removeBlacklistPlayer(context, EntityArgument.getPlayer(context, "player")))
                                                                )
                                                )
                                )
                                .then(
                                        Commands.literal("info")
                                                .executes(EDGCommand::showFilterInfo)
                                )
                                .then(
                                        Commands.literal("reset")
                                                .executes(EDGCommand::resetFilter)
                                )
                )
        ;
        CommandAliasHelper.registerWithAliases(dispatcher, getRoot(), "eroticdungeongame", "eroticdungeon", "dungeongame");
        registerCommandsInHelpSystem();
    }

    private void registerCommandsInHelpSystem() {
        ICommandHelpManager commandHelpManager = getCommandHelpManager();

        commandHelpManager.registerCommands(builder -> builder.root("edg", "commands.eroticdungeongame.root")
                .expanded(true)
                // device 命令分支
                .branch("device", "commands.help.eroticdungeongame.device", stack -> stack.hasPermission(2), deviceBuilder -> {
                    deviceBuilder.expanded(false)

                            // bind 子命令
                            .branch("bind", "commands.help.eroticdungeongame.device.bind", bindBuilder -> {
                                bindBuilder
                                        .required("pos")  // 位置参数
                                        .optional("player")  // 玩家参数（可选）
                                        .optional("code")    // 密码参数（可选）
                                        .leaf("<pos>", "commands.help.eroticdungeongame.device.bind.pos.desc")
                                        .leaf("[player]", "commands.help.eroticdungeongame.device.bind.player.desc")
                                        .leaf("[code]", "commands.help.eroticdungeongame.device.bind.code.desc");
                            })

                            // unbind 子命令
                            .branch("unbind", "commands.help.eroticdungeongame.device.unbind", unbindBuilder -> {
                                unbindBuilder
                                        .optional("pos")     // 位置参数（可选）
                                        .optional("player")  // 玩家参数（可选）
                                        .leaf("[pos]", "commands.help.eroticdungeongame.device.unbind.pos.desc")
                                        .leaf("[player]", "commands.help.eroticdungeongame.device.unbind.player.desc");
                            })

                            // lock 子命令
                            .branch("lock", "commands.help.eroticdungeongame.device.lock", lockBuilder -> {
                                lockBuilder
                                        .optional("pos")     // 位置参数（可选）
                                        .optional("player")  // 玩家参数（可选）
                                        .optional("code")    // 密码参数（可选）
                                        .leaf("[pos]", "commands.help.eroticdungeongame.device.lock.pos.desc")
                                        .leaf("[player]", "commands.help.eroticdungeongame.device.lock.player.desc")
                                        .leaf("[code]", "commands.help.eroticdungeongame.device.lock.code.desc");
                            })

                            // unlock 子命令
                            .branch("unlock", "commands.help.eroticdungeongame.device.unlock", unlockBuilder -> {
                                unlockBuilder
                                        .optional("pos")     // 位置参数（可选）
                                        .optional("player")  // 玩家参数（可选）
                                        .leaf("[pos]", "commands.help.eroticdungeongame.device.unlock.pos.desc")
                                        .leaf("[player]", "commands.help.eroticdungeongame.device.unlock.player.desc");
                            });
                })

                // key 命令分支
                .branch("key", "commands.help.eroticdungeongame.key", keyBuilder -> {
                    keyBuilder
                            .branch("lock", "commands.help.eroticdungeongame.key.lock", lockBuilder -> {
                                lockBuilder
                                        // set 子命令
                                        .branch("set", "commands.help.eroticdungeongame.key.lock.set", stack -> stack.hasPermission(2), setBuilder -> {
                                            setBuilder
                                                    .optional("code")
                                                    .leaf("[code]", "commands.help.eroticdungeongame.key.lock.set.code.desc");
                                        })
                                        // clear 子命令
                                        .leaf("clear", "commands.help.eroticdungeongame.key.lock.clear")
                                        // get 子命令
                                        .leaf("get", "commands.help.eroticdungeongame.key.lock.get");
                            });
                })
                .branch("filter", "commands.help.eroticdungeongame.filter", filterBuilder -> {
                    filterBuilder
                            .branch("mode", "commands.help.eroticdungeongame.filter.mode", modeBuilder -> {
                                modeBuilder
                                        .optional("mode")
                                        .leaf("[mode]", "commands.help.eroticdungeongame.filter.mode.desc")
                                ;
                            })
                            .branch("gamemode", "commands.help.eroticdungeongame.filter.gamemode", gameModeBuilder -> {
                                    gameModeBuilder.branch("add", "commands.help.eroticdungeongame.filter.gamemode.add", addBuilder ->
                                            addBuilder
                                                    .required("gamemode")
                                                    .leaf("<gamemode>", "commands.help.eroticdungeongame.filter.gamemode.desc")
                                    );
                                    gameModeBuilder.branch("remove", "commands.help.eroticdungeongame.filter.gamemode.remove", removeBuilder ->
                                        removeBuilder
                                                .optional("gamemode")
                                                .leaf("[gamemode]", "commands.help.eroticdungeongame.filter.gamemode.remove.desc")
                                    );
                            })
                            .branch("team", "commands.help.eroticdungeongame.filter.team", teamBuilder -> {
                                teamBuilder.branch("add", "commands.help.eroticdungeongame.filter.team.add", addBuilder ->
                                        addBuilder
                                                .required("team")
                                                .leaf("<team>", "commands.help.eroticdungeongame.filter.team.desc")
                                );
                                teamBuilder.branch("remove", "commands.help.eroticdungeongame.filter.team.remove", removeBuilder ->
                                        removeBuilder
                                                .optional("team")
                                                .leaf("[team]", "commands.help.eroticdungeongame.filter.team.remove.desc")
                                );
                            })
                            .branch("tag", "commands.help.eroticdungeongame.filter.tag", tagBuilder -> {
                                tagBuilder.branch("add", "commands.help.eroticdungeongame.filter.tag.add", addBuilder ->
                                        addBuilder
                                                .required("tag")
                                                .leaf("<tag>", "commands.help.eroticdungeongame.filter.tag.desc")
                                );
                                tagBuilder.branch("remove", "commands.help.eroticdungeongame.filter.tag.remove", removeBuilder ->
                                        removeBuilder
                                                .optional("tag")
                                                .leaf("[tag]", "commands.help.eroticdungeongame.filter.tag.remove.desc")
                                );
                            })
                            .branch("workpos", "commands.help.eroticdungeongame.filter.workpos", workposBuilder -> {
                                workposBuilder.branch("set", "commands.help.eroticdungeongame.filter.workpos.set", addBuilder ->
                                        addBuilder
                                                .required("workpos")
                                                .leaf("<workpos>", "commands.help.eroticdungeongame.filter.workpos.set.desc")
                                );
                                workposBuilder.leaf("remove", "commands.help.eroticdungeongame.filter.workpos.remove.desc");
                            })
                            .branch("whitelist", "commands.help.eroticdungeongame.filter.whitelist", whitelistBuilder -> {
                                whitelistBuilder.branch("add", "commands.help.eroticdungeongame.filter.whitelist.add", addBuilder ->
                                        addBuilder
                                                .required("whitelist")
                                                .leaf("<whitelist>", "commands.help.eroticdungeongame.filter.whitelist.desc")
                                );
                                whitelistBuilder.branch("remove", "commands.help.eroticdungeongame.filter.whitelist.remove", removeBuilder ->
                                        removeBuilder
                                                .optional("whitelist")
                                                .leaf("[whitelist]", "commands.help.eroticdungeongame.filter.whitelist.remove.desc")
                                );
                            })
                            .branch("blacklist", "commands.help.eroticdungeongame.filter.blacklist", blacklistBuilder -> {
                                blacklistBuilder.branch("add", "commands.help.eroticdungeongame.filter.blacklist.add", addBuilder ->
                                        addBuilder
                                                .required("blacklist")
                                                .leaf("<blacklist>", "commands.help.eroticdungeongame.filter.blacklist.desc")
                                );
                                blacklistBuilder.branch("remove", "commands.help.eroticdungeongame.filter.blacklist.remove", removeBuilder ->
                                        removeBuilder
                                                .optional("blacklist")
                                                .leaf("[blacklist]", "commands.help.eroticdungeongame.filter.blacklist.remove.desc")
                                );
                            })
                            .leaf("info", "commands.help.eroticdungeongame.filter.info")
                            .leaf("reset", "commands.help.eroticdungeongame.filter.reset")
                    ;
                })

        );
    }

    // ============ Device Bind Methods ============
    private int edg$device$bind$pos$self(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        CommandSourceStack source = context.getSource();
        ServerPlayer player = source.getPlayerOrException();

        if (SeatService.bindPlayerToSeat(player, pos)) {
            SeatService.playBindingAnimation(player, Objects.requireNonNull(FurnitureHelper.getSeatType(source.getLevel().getBlockState(pos).getBlock())));
            source.sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.device.bind.pos.self",
                            formatBlockPos(pos)), true);
            return 1;
        } else {
            return bind$fail(pos, player, source);
        }
    }

    private int edg$device$bind$pos$player(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        CommandSourceStack source = context.getSource();
        if (SeatService.bindPlayerToSeat(targetPlayer, pos)) {
            SeatService.playBindingAnimation(targetPlayer, Objects.requireNonNull(FurnitureHelper.getSeatType(source.getLevel().getBlockState(pos).getBlock())));
            source.sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.device.bind.pos",
                            targetPlayer.getDisplayName(), formatBlockPos(pos)), true);
            return 1;
        } else {
            return bind$fail(pos, targetPlayer, source);
        }
    }

    private int bind$fail(BlockPos pos, ServerPlayer targetPlayer, CommandSourceStack source) {
        BlockState blockState = targetPlayer.level().getBlockState(pos);
        if (blockState.getBlock() instanceof ISeatBlock) {
            Boolean occupied = blockState.getValue(ISeatBlock.OCCUPIED);
            if (occupied) {
                source.sendFailure(Component.translatable("command.eroticdungeongame.device.fail.device_is_occupied",
                        formatBlockPos(pos)));
                return -1;
            } else if (targetPlayer.isPassenger() && targetPlayer.getVehicle() != null && targetPlayer.getVehicle() instanceof SeatEntity seat) {
                source.sendFailure(Component.translatable("command.eroticdungeongame.device.fail.in_other_device", formatBlockPos(seat.getLinkedBlockPos()), targetPlayer.getDisplayName()));
                return -4;
            }else {
                source.sendFailure(Component.translatable("command.eroticdungeongame.device.fail.unknown"));
                return -3;
            }
        } else {
            source.sendFailure(Component.translatable("command.eroticdungeongame.device.fail.not_found_device",
                    formatBlockPos(pos)));
            return -2;
        }
    }

    private Component formatBlockPos(BlockPos pos) {
        return Component.literal(String.format("[%d, %d, %d]", pos.getX(), pos.getY(), pos.getZ()))
                .setStyle(Style.EMPTY
                        .withColor(net.minecraft.ChatFormatting.GREEN)
                        .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                                Component.translatable("description.eroticdungeongame.click_to_teleport")))
                        .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND,
                                String.format("/tp @p %d %d %d", pos.getX(), pos.getY(), pos.getZ()))));
    }

    private Component generateCodeComponent(long code) {
        return Component.translatable("description.eroticdungeongame.key_content", code).append(
                DeviceKeyItem.turnLockCodeToComponent(code)
                        .copy()
                        .setStyle(Style.EMPTY
                                .withColor(net.minecraft.ChatFormatting.GOLD)
                                .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
                                        Component.translatable("description.eroticdungeongame.click_to_copy")))
                                .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.valueOf(code))))
        );
    }

    private int edg$device$bind$pos$code$self(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        long code = LongArgumentType.getLong(context, "code");
        ServerPlayer player = context.getSource().getPlayerOrException();
        CommandSourceStack source = context.getSource();

        if (code == -1) {
            code = DeviceKeyItem.generateLockCode(player);
        }

        if (SeatService.bindPlayerToSeat(player, pos)) {
            long finalCode = code;
            return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(player,
                    data -> {
                        BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                        if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                            SeatService.playBindingAnimation(player, Objects.requireNonNull(FurnitureHelper.getSeatType(seatBlockEntity.getBlockState().getBlock())));
                            seatBlockEntity.setLockCode(finalCode);
                            source.sendSuccess(() -> Component.translatable(
                                    "command.eroticdungeongame.device.bind.pos.self.with_code",
                                    formatBlockPos(pos),
                                    generateCodeComponent(finalCode)), true);
                            return 1;
                        }
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.bind.pos.self",
                                formatBlockPos(pos)), true);
                        source.sendFailure(Component.translatable(
                                "command.eroticdungeongame.device.lock.pos.fail",
                                formatBlockPos(pos)));
                        return 0;
                    },
                    () -> {
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.bind.pos.self",
                                formatBlockPos(pos)), true);
                        source.sendFailure(Component.translatable(
                                "command.eroticdungeongame.device.lock.pos.fail",
                                formatBlockPos(pos)));
                        return 0;
                    }
            );
        } else {
            return bind$fail(pos, player, source);
        }
    }

    private int edg$device$bind$pos$player$code(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        long code = LongArgumentType.getLong(context, "code");
        CommandSourceStack source = context.getSource();

        if (code == -1) {
            code = DeviceKeyItem.generateLockCode(targetPlayer);
        }

        if (SeatService.bindPlayerToSeat(targetPlayer, pos)) {
            long finalCode = code;
            return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(targetPlayer,
                    data -> {
                        BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                        if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                            SeatService.playBindingAnimation(targetPlayer, Objects.requireNonNull(FurnitureHelper.getSeatType(seatBlockEntity.getBlockState().getBlock())));
                            seatBlockEntity.setLockCode(finalCode);
                            source.sendSuccess(() -> Component.translatable(
                                    "command.eroticdungeongame.device.bind.pos.with_code",
                                    targetPlayer.getDisplayName(),
                                    formatBlockPos(pos),
                                    generateCodeComponent(finalCode)), true);
                            return 1;
                        }
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.bind.pos",
                                targetPlayer.getDisplayName(),
                                formatBlockPos(pos)), true);
                        source.sendFailure(Component.translatable(
                                "command.eroticdungeongame.device.lock.pos.fail",
                                formatBlockPos(pos)));
                        return 0;
                    },
                    () -> {
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.bind.pos",
                                targetPlayer.getDisplayName(),
                                formatBlockPos(pos)), true);
                        source.sendFailure(Component.translatable(
                                "command.eroticdungeongame.device.lock.pos.fail",
                                formatBlockPos(pos)));
                        return 0;
                    }
            );
        } else {
            return bind$fail(pos, targetPlayer, source);
        }
    }

    // ============ Device Unbind Methods ============
    private int edg$device$unbind$self(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        CommandSourceStack source = context.getSource();

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(player,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        if (SeatService.releasePlayer(player.level(), data.getDeviceMainBlockPos())) {
                            source.sendSuccess(() -> Component.translatable(
                                    "command.eroticdungeongame.device.unbind.self.success",
                                    player.getDisplayName()), true);
                            return 1;
                        }
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unbind.self.fail"));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unbind.self.fail"));
                    return 0;
                }
        );
    }

    private int edg$device$unbind$pos(CommandContext<CommandSourceStack> context) {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        CommandSourceStack source = context.getSource();

        BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(source.getLevel(), pos);
        if (seatBlockEntity != null) {
            UUID boundPlayer = seatBlockEntity.getBoundPlayerUUID();
            if (boundPlayer != null) {
                if (SeatService.releasePlayerFromBlock(source.getLevel(), pos)) {
                    source.sendSuccess(() -> Component.translatable(
                            "command.eroticdungeongame.device.unbind.pos.success",
                            formatBlockPos(pos)), true);
                    return 1;
                }
            }
        }
        source.sendFailure(Component.translatable(
                "command.eroticdungeongame.device.unbind.pos.fail",
                formatBlockPos(pos)));
        return 0;
    }

    private int edg$device$unbind$player(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        CommandSourceStack source = context.getSource();

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(targetPlayer,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        if (SeatService.releasePlayer(source.getLevel(), data.getDeviceMainBlockPos())) {
                            source.sendSuccess(() -> Component.translatable(
                                    "command.eroticdungeongame.device.unbind.player.success",
                                    targetPlayer.getDisplayName()), true);
                            return 1;
                        }
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unbind.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unbind.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                }
        );
    }

    // ============ Device Lock Methods ============
    private int edg$device$lock$self(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        CommandSourceStack source = context.getSource();
        long randomCode = generateRandomCode(source.getLevel());

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(player,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        seatBlockEntity.setLockCode(randomCode);
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.lock.self.success",
                                generateCodeComponent(randomCode)), true);
                        return 1;
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.self.fail"));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.self.fail"));
                    return 0;
                }
        );
    }

    private int edg$device$lock$pos(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        CommandSourceStack source = context.getSource();
        long randomCode = generateRandomCode(source.getLevel());

        BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(source.getLevel(), pos);
        if (seatBlockEntity != null) {
            seatBlockEntity.setLockCode(randomCode);
            source.sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.device.lock.pos.success",
                    formatBlockPos(pos),
                    generateCodeComponent(randomCode)), true);
            return 1;
        }
        source.sendFailure(Component.translatable(
                "command.eroticdungeongame.device.lock.pos.fail",
                formatBlockPos(pos)));
        return 0;
    }

    private int edg$device$lock$pos$code(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        long code = LongArgumentType.getLong(context, "code");
        CommandSourceStack source = context.getSource();

        BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(source.getLevel(), pos);
        if (seatBlockEntity != null) {
            seatBlockEntity.setLockCode(code);
            source.sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.device.lock.pos.success",
                    formatBlockPos(pos),
                    generateCodeComponent(code)), true);
            return 1;
        }
        source.sendFailure(Component.translatable(
                "command.eroticdungeongame.device.lock.pos.fail",
                formatBlockPos(pos)));
        return 0;
    }

    private int edg$device$lock$player(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        CommandSourceStack source = context.getSource();
        long randomCode = generateRandomCode(source.getLevel());

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(targetPlayer,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        seatBlockEntity.setLockCode(randomCode);
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.lock.player.success",
                                targetPlayer.getDisplayName(),
                                generateCodeComponent(randomCode)), true);
                        return 1;
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                }
        );
    }

    private int edg$device$lock$player$code(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        long code = LongArgumentType.getLong(context, "code");
        CommandSourceStack source = context.getSource();

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(targetPlayer,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        seatBlockEntity.setLockCode(code);
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.lock.player.success",
                                targetPlayer.getDisplayName(),
                                generateCodeComponent(code)), true);
                        return 1;
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.lock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                }
        );
    }

    // ============ Device Unlock Methods ============
    private int edg$device$unlock$self(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        CommandSourceStack source = context.getSource();

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(player,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        seatBlockEntity.setLockCode(-1L);
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.unlock.self.success"), true);
                        return 1;
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unlock.self.fail"));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unlock.self.fail"));
                    return 0;
                }
        );
    }

    private int edg$device$unlock$pos(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
        CommandSourceStack source = context.getSource();

        BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(source.getLevel(), pos);
        if (seatBlockEntity != null) {
            seatBlockEntity.setLockCode(-1L);
            source.sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.device.unlock.pos.success",
                    formatBlockPos(pos)), true);
            return 1;
        }
        source.sendFailure(Component.translatable(
                "command.eroticdungeongame.device.unlock.pos.fail",
                formatBlockPos(pos)));
        return 0;
    }

    private int edg$device$unlock$player(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        CommandSourceStack source = context.getSource();

        return Services.WORK_SPACE.tryToDoIfInDeviceAndRet(targetPlayer,
                data -> {
                    BlockEntity blockEntity = source.getLevel().getBlockEntity(data.getDeviceMainBlockPos());
                    if (blockEntity instanceof BaseSeatBlockEntity seatBlockEntity) {
                        seatBlockEntity.setLockCode(-1L);
                        source.sendSuccess(() -> Component.translatable(
                                "command.eroticdungeongame.device.unlock.player.success",
                                targetPlayer.getDisplayName()), true);
                        return 1;
                    }
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unlock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                },
                () -> {
                    source.sendFailure(Component.translatable(
                            "command.eroticdungeongame.device.unlock.player.fail",
                            targetPlayer.getDisplayName()));
                    return 0;
                }
        );
    }

    // ============ Key Lock Methods ============
    private int edg$key$lock$set(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        CommandSourceStack source = context.getSource();

        ItemStack heldItem = player.getMainHandItem();
        if (heldItem.getItem() instanceof DeviceKeyItem keyItem) {
            long randomCode = generateRandomCode(source.getLevel());
            DeviceKeyItem.setCode(heldItem, randomCode);

            source.sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.key.lock.set.success",
                    generateCodeComponent(randomCode)), true);
            return 1;
        }

        source.sendFailure(Component.translatable(
                "command.eroticdungeongame.key.lock.set.fail"));
        return 0;
    }

    private int edg$key$lock$set$code(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        long code = LongArgumentType.getLong(context, "code");

        ItemStack heldItem = player.getMainHandItem();
        if (heldItem.getItem() instanceof DeviceKeyItem keyItem) {
            DeviceKeyItem.setCode(heldItem, code);

            context.getSource().sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.key.lock.set.success",
                    generateCodeComponent(code)), true);
            return 1;
        }

        context.getSource().sendFailure(Component.translatable(
                "command.eroticdungeongame.key.lock.set.fail"));
        return 0;
    }

    private int edg$key$lock$clear(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();

        ItemStack heldItem = player.getMainHandItem();
        if (heldItem.getItem() instanceof DeviceKeyItem keyItem) {
            DeviceKeyItem.clearCode(heldItem);

            context.getSource().sendSuccess(() -> Component.translatable(
                    "command.eroticdungeongame.key.lock.clear.success"), true);
            return 1;
        }

        context.getSource().sendFailure(Component.translatable(
                "command.eroticdungeongame.key.lock.clear.fail"));
        return 0;
    }

    private int edg$key$lock$get(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();

        ItemStack heldItem = player.getMainHandItem();
        if (heldItem.getItem() instanceof DeviceKeyItem keyItem) {
            long currentCode = DeviceKeyItem.getCode(heldItem);

            if (currentCode != 0L) {
                context.getSource().sendSuccess(() -> Component.translatable(
                        "command.eroticdungeongame.key.lock.get.success",
                        generateCodeComponent(currentCode)), false);
            } else {
                context.getSource().sendSuccess(() -> Component.translatable(
                        "command.eroticdungeongame.key.lock.get.empty"), false);
            }
            return 1;
        }

        context.getSource().sendFailure(Component.translatable(
                "command.eroticdungeongame.key.lock.get.fail"));
        return 0;
    }
    private static int giveFilter(CommandContext<CommandSourceStack> context, Collection<ServerPlayer> targets, int amount) {
        for (ServerPlayer player : targets) {
            ItemStack filter = FilterItem.createFilter(FilterItem.FilterMode.WHITELIST);
            filter.setCount(amount);
            player.getInventory().add(filter);
        }

        String key = targets.size() == 1 ? "command.eroticdungeongame.filter.give.single" : "command.eroticdungeongame.filter.give.multiple";
        context.getSource().sendSuccess(() ->
                Component.translatable(key, targets.size(), amount), true);

        return targets.size();
    }

    private static int setFilterMode(CommandContext<CommandSourceStack> context, String modeStr) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.FilterMode mode = modeStr.equalsIgnoreCase("whitelist") ? FilterItem.FilterMode.WHITELIST : FilterItem.FilterMode.BLACKLIST;
        FilterItem.setFilterMode(stack, mode);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.mode.set", modeStr), true);

        return 1;
    }

    private static int addGameMode(CommandContext<CommandSourceStack> context, String gameModeStr) throws CommandSyntaxException {
        return modifyGameMode(context, gameModeStr, true);
    }

    private static int removeGameMode(CommandContext<CommandSourceStack> context, String gameModeStr) throws CommandSyntaxException {
        return modifyGameMode(context, gameModeStr, false);
    }

    private static int modifyGameMode(CommandContext<CommandSourceStack> context, String gameModeStr, boolean add) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.GameMode gameMode = Arrays.stream(FilterItem.GameMode.values())
                .filter(gm -> gm.getName().equalsIgnoreCase(gameModeStr))
                .findFirst()
                .orElse(null);

        if (gameMode == null) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.invalid_gamemode"));
            return 0;
        }

        if (add) {
            FilterItem.addGameMode(stack, gameMode);
            context.getSource().sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.filter.gamemode.add", gameModeStr), true);
        } else {
            FilterItem.removeGameMode(stack, gameMode);
            context.getSource().sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.filter.gamemode.remove", gameModeStr), true);
        }

        return 1;
    }

    private static int clearGameModes(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 清除所有游戏模式
        for (FilterItem.GameMode gm : FilterItem.GameMode.values()) {
            FilterItem.removeGameMode(stack, gm);
        }

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.gamemode.clear"), true);

        return 1;
    }

    private static int addTag(CommandContext<CommandSourceStack> context, String tag) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.addTag(stack, tag);
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.tag.add", tag), true);

        return 1;
    }

    private static int removeTag(CommandContext<CommandSourceStack> context, String tag) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加移除标签的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.tag.remove", tag), true);

        return 1;
    }

    private static int clearTags(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加清除所有标签的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.tag.clear"), true);

        return 1;
    }

    private static int addTeam(CommandContext<CommandSourceStack> context, String team) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.addTeam(stack, team);
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.team.add", team), true);

        return 1;
    }

    private static int removeTeam(CommandContext<CommandSourceStack> context, String team) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加移除队伍的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.team.remove", team), true);

        return 1;
    }

    private static int clearTeams(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加清除所有队伍的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.team.clear"), true);

        return 1;
    }

    private static int setWorkPosition(CommandContext<CommandSourceStack> context, BlockPos pos) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        String dimension = player.level().dimension().location().toString();
        FilterItem.setWorkPosition(stack, pos, dimension);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.workpos.set",
                        pos.getX(), pos.getY(), pos.getZ(), dimension), true);

        return 1;
    }

    private static int removeWorkPosition(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.removeWorkPosition(stack);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.workpos.remove"), true);

        return 1;
    }

    private static int addWhitelistPlayer(CommandContext<CommandSourceStack> context, ServerPlayer target) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.addWhitelistPlayer(stack, target.getUUID().toString());
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.whitelist.add", target.getName()), true);

        return 1;
    }

    private static int removeWhitelistPlayer(CommandContext<CommandSourceStack> context, ServerPlayer target) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.removeWhitelistPlayer(stack, target.getUUID().toString());
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.whitelist.remove", target.getName()), true);

        return 1;
    }

    private static int clearWhitelist(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加清除白名单的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.whitelist.clear"), true);

        return 1;
    }

    private static int addBlacklistPlayer(CommandContext<CommandSourceStack> context, ServerPlayer target) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.addBlacklistPlayer(stack, target.getUUID().toString());
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.blacklist.add", target.getName()), true);

        return 1;
    }

    private static int removeBlacklistPlayer(CommandContext<CommandSourceStack> context, ServerPlayer target) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.removeBlacklistPlayer(stack, target.getUUID().toString());
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.blacklist.remove", target.getName()), true);

        return 1;
    }

    private static int clearBlacklist(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 需要添加清除黑名单的方法
        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.blacklist.clear"), true);

        return 1;
    }

    private static int listPlayers(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        var whitelist = FilterItem.getWhitelistPlayers(stack);
        var blacklist = FilterItem.getBlacklistPlayers(stack);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.player.list.header"), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.player.list.whitelist", whitelist.size()), true);
        whitelist.forEach(uuid ->
                context.getSource().sendSuccess(() -> Component.literal("  - " + uuid), true));

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.player.list.blacklist", blacklist.size()), true);
        blacklist.forEach(uuid ->
                context.getSource().sendSuccess(() -> Component.literal("  - " + uuid), true));

        return 1;
    }

    private static int showFilterInfo(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        FilterItem.FilterMode mode = FilterItem.getFilterMode(stack);
        var gameModes = FilterItem.getGameModes(stack);
        var tags = FilterItem.getTags(stack);
        var teams = FilterItem.getTeams(stack);
        var workPos = FilterItem.getWorkPosition(stack);
        var workDim = FilterItem.getWorkDimension(stack);
        var whitelist = FilterItem.getWhitelistPlayers(stack);
        var blacklist = FilterItem.getBlacklistPlayers(stack);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.header"), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.mode", mode.getName()), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.gamemodes",
                        gameModes.stream().map(FilterItem.GameMode::getName).collect(Collectors.joining(", "))), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.tags",
                        String.join(", ", tags)), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.teams",
                        String.join(", ", teams)), true);

        if (workPos != null) {
            context.getSource().sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.filter.info.workpos",
                            workPos.getX(), workPos.getY(), workPos.getZ(), workDim), true);
        } else {
            context.getSource().sendSuccess(() ->
                    Component.translatable("command.eroticdungeongame.filter.info.workpos.none"), true);
        }

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.whitelist", whitelist.size()), true);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.info.blacklist", blacklist.size()), true);

        return 1;
    }

    private static int resetFilter(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
        ServerPlayer player = context.getSource().getPlayerOrException();
        ItemStack stack = player.getMainHandItem();

        if (!(stack.getItem() instanceof FilterItem)) {
            context.getSource().sendFailure(Component.translatable("command.eroticdungeongame.filter.error.not_filter"));
            return 0;
        }

        // 重置为新的过滤器
        ItemStack newFilter = FilterItem.createFilter(FilterItem.FilterMode.WHITELIST);
        player.setItemInHand(player.getUsedItemHand(), newFilter);

        context.getSource().sendSuccess(() ->
                Component.translatable("command.eroticdungeongame.filter.reset"), true);

        return 1;
    }

    // ============ Helper Methods ============
    private long generateRandomCode(ServerLevel serverLevel) {
        return DeviceKeyItem.generateLockCode(FakePlayerFactory.getMinecraft(serverLevel));
    }

    @Nullable
    @Override
    public LiteralArgumentBuilder<CommandSourceStack> getHelpHead() {
        return Commands.literal("edg");
    }
}