package com.tiedup.remake.commands.subcommands;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.tiedup.remake.commands.CommandHelper;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import net.minecraft.ChatFormatting;
import net.minecraft.resources.ResourceLocation;
import com.tiedup.remake.state.PlayerBindState;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;

@SuppressWarnings("null")
public class BindCommands {

    public static void register(LiteralArgumentBuilder<CommandSourceStack> root) {
        // /tiedup tie <player>
        root.then(
            Commands.literal("tie")
                .requires(CommandHelper.REQUIRES_OP)
                .then(
                    Commands.argument(
                        "player",
                        EntityArgument.player()
                    ).executes(BindCommands::tie)
                )
        );
        // /tiedup untie <player>
        root.then(
            Commands.literal("untie")
                .requires(CommandHelper.REQUIRES_OP)
                .then(
                    Commands.argument(
                        "player",
                        EntityArgument.player()
                    ).executes(BindCommands::untie)
                )
        );
    }

    static int tie(CommandContext<CommandSourceStack> context)
        throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        PlayerBindState state = PlayerBindState.getInstance(targetPlayer);

        if (state == null) {
            context
                .getSource()
                .sendFailure(Component.translatable("command.tiedup.error.no_state"));
            return 0;
        }

        if (state.isTiedUp()) {
            context
                .getSource()
                .sendFailure(
                    Component.translatable(
                        "command.tiedup.bind.already_tied",
                        targetPlayer.getName().getString()
                    )
                );
            return 0;
        }

        ItemStack ropes = DataDrivenBondageItem.createStack(ResourceLocation.fromNamespaceAndPath("tiedup", "ropes"));
        state.putBindOn(ropes);

        CommandHelper.syncPlayerState(targetPlayer, state);

        context
            .getSource()
            .sendSuccess(
                () ->
                    Component.translatable(
                        "command.tiedup.bind.tied",
                        targetPlayer.getName().getString()
                    ).withStyle(ChatFormatting.GREEN),
                true
            );
        SystemMessageManager.sendTiedUp(
            context.getSource().getEntity(),
            targetPlayer
        );

        return 1;
    }

    static int untie(CommandContext<CommandSourceStack> context)
        throws CommandSyntaxException {
        ServerPlayer targetPlayer = EntityArgument.getPlayer(context, "player");
        PlayerBindState state = PlayerBindState.getInstance(targetPlayer);

        if (state == null) {
            context
                .getSource()
                .sendFailure(Component.translatable("command.tiedup.error.no_state"));
            return 0;
        }

        if (
            !state.isTiedUp() &&
            !state.isGagged() &&
            !state.isBlindfolded() &&
            !state.hasCollar()
        ) {
            context
                .getSource()
                .sendFailure(
                    Component.translatable(
                        "command.tiedup.bind.not_restrained",
                        targetPlayer.getName().getString()
                    )
                );
            return 0;
        }

        boolean removed = false;
        if (state.isTiedUp()) {
            state.takeBindOff();
            removed = true;
        }
        if (state.isGagged()) {
            state.takeGagOff();
            removed = true;
        }
        if (state.isBlindfolded()) {
            state.takeBlindfoldOff();
            removed = true;
        }
        if (state.hasCollar()) {
            state.takeCollarOff();
            removed = true;
        }
        if (state.hasEarplugs()) {
            state.takeEarplugsOff();
            removed = true;
        }

        if (removed) {
            CommandHelper.syncPlayerState(targetPlayer, state);

            context
                .getSource()
                .sendSuccess(
                    () ->
                        Component.translatable(
                            "command.tiedup.bind.freed",
                            targetPlayer.getName().getString()
                        ).withStyle(ChatFormatting.GREEN),
                    true
                );
            SystemMessageManager.sendFreed(targetPlayer);

            return 1;
        }

        return 0;
    }

}
