package com.tiedup.remake.v2.bondage;

import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemDefinition;
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenItemRegistry;
import java.util.Map;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;

/**
 * Static utilities for bind mode operations on any bondage item stack (V1 or V2).
 *
 * <p>Bind mode determines whether a bind restrains arms, legs, or both.
 * The mode is stored in the stack's NBT tag {@code "bindMode"}.</p>
 */
public final class BindModeHelper {

    private BindModeHelper() {}

    private static final String NBT_BIND_MODE = "bindMode";

    public static final String MODE_FULL = "full";
    public static final String MODE_ARMS = "arms";
    public static final String MODE_LEGS = "legs";

    private static final String[] MODE_CYCLE = { MODE_FULL, MODE_ARMS, MODE_LEGS };

    private static final Map<String, String> MODE_TRANSLATION_KEYS = Map.of(
        MODE_FULL, "tiedup.bindmode.full",
        MODE_ARMS, "tiedup.bindmode.arms",
        MODE_LEGS, "tiedup.bindmode.legs"
    );

    /**
     * Check if the given stack is a bind item (ARMS-region data-driven item).
     */
    public static boolean isBindItem(ItemStack stack) {
        if (stack.isEmpty()) return false;
        // V2: check data-driven definition
        DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack);
        if (def != null) {
            return def.occupiedRegions().contains(BodyRegionV2.ARMS);
        }
        // No V2 definition found
        return false;
    }

    /**
     * Get the bind mode ID from the stack's NBT.
     * @return "full", "arms", or "legs" (defaults to "full")
     */
    public static String getBindModeId(ItemStack stack) {
        if (stack.isEmpty()) return MODE_FULL;
        CompoundTag tag = stack.getTag();
        if (tag == null || !tag.contains(NBT_BIND_MODE)) return MODE_FULL;
        String value = tag.getString(NBT_BIND_MODE);
        if (MODE_ARMS.equals(value) || MODE_LEGS.equals(value)) return value;
        return MODE_FULL;
    }

    /** True if arms are restrained (mode is "arms" or "full"). */
    public static boolean hasArmsBound(ItemStack stack) {
        String mode = getBindModeId(stack);
        return MODE_ARMS.equals(mode) || MODE_FULL.equals(mode);
    }

    /** True if legs are restrained (mode is "legs" or "full"). */
    public static boolean hasLegsBound(ItemStack stack) {
        String mode = getBindModeId(stack);
        return MODE_LEGS.equals(mode) || MODE_FULL.equals(mode);
    }

    /**
     * Cycle bind mode: full → arms → legs → full.
     * @return the new mode ID
     */
    public static String cycleBindModeId(ItemStack stack) {
        String current = getBindModeId(stack);
        String next = MODE_FULL;
        for (int i = 0; i < MODE_CYCLE.length; i++) {
            if (MODE_CYCLE[i].equals(current)) {
                next = MODE_CYCLE[(i + 1) % MODE_CYCLE.length];
                break;
            }
        }
        stack.getOrCreateTag().putString(NBT_BIND_MODE, next);
        return next;
    }

    /** Get the translation key for the current bind mode. */
    public static String getBindModeTranslationKey(ItemStack stack) {
        return MODE_TRANSLATION_KEYS.getOrDefault(getBindModeId(stack), "tiedup.bindmode.full");
    }
}
