package com.tiedup.remake.commands;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.items.base.KnifeVariant;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
import java.util.Optional;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;

/**
 * Utility commands.
 *
 * Commands:
 *   /kidnapset - Get a starter kit of mod items
 *   /kidnapreload [type] - Reload data files (jobs, sales, gagtalk)
 */
public class KidnapSetCommand {

    public static void register(
        CommandDispatcher<CommandSourceStack> dispatcher
    ) {
        dispatcher.register(createKidnapSetCommand());
        dispatcher.register(createKidnapReloadCommand());
    }

    /**
     * Create the kidnapset command builder (for use as subcommand of /tiedup).
     * @return The command builder
     */
    public static com.mojang.brigadier.builder.LiteralArgumentBuilder<
        CommandSourceStack
    > createKidnapSetCommand() {
        return Commands.literal("kidnapset")
            .requires(CommandHelper.REQUIRES_OP)
            .executes(KidnapSetCommand::giveSet);
    }

    /**
     * Create the kidnapreload command builder (for use as subcommand of /tiedup).
     * @return The command builder
     */
    public static com.mojang.brigadier.builder.LiteralArgumentBuilder<
        CommandSourceStack
    > createKidnapReloadCommand() {
        return Commands.literal("kidnapreload")
            .requires(CommandHelper.REQUIRES_OP)
            .executes(ctx -> reload(ctx, "all"))
            .then(Commands.literal("jobs").executes(ctx -> reload(ctx, "jobs")))
            .then(
                Commands.literal("sales").executes(ctx -> reload(ctx, "sales"))
            )
            .then(
                Commands.literal("gagtalk").executes(ctx ->
                    reload(ctx, "gagtalk")
                )
            )
            .then(Commands.literal("all").executes(ctx -> reload(ctx, "all")));
    }

    /**
     * Give a starter kit of mod items to the player.
     */
    private static int giveSet(CommandContext<CommandSourceStack> context)
        throws CommandSyntaxException {
        CommandSourceStack source = context.getSource();

        Optional<ServerPlayer> playerOpt = CommandHelper.getPlayerOrFail(
            source
        );
        if (playerOpt.isEmpty()) return 0;
        ServerPlayer player = playerOpt.get();

        int given = 0;

        // Binds
        given += giveDataDrivenItems(player, "ropes", 8);
        given += giveDataDrivenItems(player, "chain", 4);
        given += giveDataDrivenItems(player, "leather_straps", 4);

        // Gags
        given += giveDataDrivenItems(player, "cloth_gag", 4);
        given += giveDataDrivenItems(player, "ball_gag", 4);
        given += giveDataDrivenItems(player, "tape_gag", 4);

        // Blindfolds
        given += giveDataDrivenItems(player, "classic_blindfold", 4);
        given += giveDataDrivenItems(player, "blindfold_mask", 2);

        // Collars (data-driven)
        ItemStack classicCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack(
            net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("tiedup", "classic_collar"));
        classicCollars.setCount(4);
        given += giveItem(player, classicCollars);
        ItemStack shockCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack(
            net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("tiedup", "shock_collar"));
        shockCollars.setCount(2);
        given += giveItem(player, shockCollars);
        ItemStack gpsCollars = com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem.createStack(
            net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("tiedup", "gps_collar"));
        gpsCollars.setCount(2);
        given += giveItem(player, gpsCollars);

        // Tools
        given += giveItem(
            player,
            new ItemStack(ModItems.getKnife(KnifeVariant.IRON), 2)
        );
        given += giveItem(
            player,
            new ItemStack(ModItems.getKnife(KnifeVariant.GOLDEN), 1)
        );
        given += giveItem(player, new ItemStack(ModItems.WHIP.get(), 1));
        given += giveItem(player, new ItemStack(ModItems.PADDLE.get(), 1));

        // Controllers
        given += giveItem(
            player,
            new ItemStack(ModItems.SHOCKER_CONTROLLER.get(), 1)
        );
        given += giveItem(player, new ItemStack(ModItems.GPS_LOCATOR.get(), 1));

        // Keys and locks
        given += giveItem(player, new ItemStack(ModItems.PADLOCK.get(), 4));
        given += giveItem(player, new ItemStack(ModItems.COLLAR_KEY.get(), 2));
        given += giveItem(player, new ItemStack(ModItems.MASTER_KEY.get(), 1));

        // Earplugs
        given += giveDataDrivenItems(player, "classic_earplugs", 4);

        // Rope arrows
        given += giveItem(player, new ItemStack(ModItems.ROPE_ARROW.get(), 16));

        // Chloroform
        given += giveItem(
            player,
            new ItemStack(ModItems.CHLOROFORM_BOTTLE.get(), 2)
        );
        given += giveItem(player, new ItemStack(ModItems.RAG.get(), 4));

        int finalGiven = given;
        source.sendSuccess(
            () ->
                Component.translatable(
                    "command.tiedup.kidnapset.gave", finalGiven
                ).withStyle(ChatFormatting.GREEN),
            true
        );

        return finalGiven;
    }

    private static int giveDataDrivenItems(ServerPlayer player, String itemName, int count) {
        int given = 0;
        for (int i = 0; i < count; i++) {
            ItemStack stack = DataDrivenBondageItem.createStack(ResourceLocation.fromNamespaceAndPath("tiedup", itemName));
            if (!stack.isEmpty()) {
                giveItem(player, stack);
                given++;
            }
        }
        return given;
    }

    private static int giveItem(ServerPlayer player, ItemStack stack) {
        if (!player.getInventory().add(stack)) {
            // Drop on ground if inventory full
            player.drop(stack, false);
        }
        return 1;
    }

    /**
     * Reload data files.
     */
    private static int reload(
        CommandContext<CommandSourceStack> context,
        String type
    ) {
        CommandSourceStack source = context.getSource();
        int reloaded = 0;

        if (type.equals("all") || type.equals("jobs")) {
            com.tiedup.remake.util.tasks.JobLoader.init();
            reloaded++;
        }

        if (type.equals("all") || type.equals("sales")) {
            com.tiedup.remake.util.tasks.SaleLoader.init();
            reloaded++;
        }

        if (type.equals("all") || type.equals("gagtalk")) {
            // GagTalkManager is code-based (no external data files)
            // No reload needed - materials/logic defined in GagMaterial enum
            reloaded++;
        }

        int finalReloaded = reloaded;
        source.sendSuccess(
            () ->
                Component.translatable(
                    "command.tiedup.kidnapreload.reloaded",
                    type.equals("all") ? "all data files" : type,
                    finalReloaded
                ).withStyle(ChatFormatting.GREEN),
            true
        );

        return reloaded;
    }
}
