package com.tiedup.remake.v2.bondage.movement;

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.world.item.ItemStack;

/**
 * Resolves the winning movement style from a player's equipped bondage items.
 *
 * <p>Shared class (client + server). Deterministic: same items produce the same result.
 * The highest-severity style wins. Tiebreaker: lowest {@link BodyRegionV2#ordinal()}.</p>
 *
 * <p>The winning item's {@link MovementModifier} (if present) overrides the style's
 * default speed/jump values. Modifiers from lower-severity items are ignored.</p>
 */
public final class MovementStyleResolver {

    private MovementStyleResolver() {}

    /**
     * Resolve the winning movement style from all equipped items.
     *
     * <p>Uses V2 data-driven definitions to determine movement style.</p>
     *
     * @param equipped map of region to ItemStack (from {@code IV2BondageEquipment.getAllEquipped()})
     * @return the resolved movement, or {@link ResolvedMovement#NONE} if no styled items
     */
    public static ResolvedMovement resolve(
        Map<BodyRegionV2, ItemStack> equipped
    ) {
        if (equipped == null || equipped.isEmpty()) {
            return ResolvedMovement.NONE;
        }

        MovementStyle bestStyle = null;
        float bestSpeed = 1.0f;
        boolean bestJumpDisabled = false;
        int bestSeverity = -1;
        int bestRegionOrdinal = Integer.MAX_VALUE;

        for (Map.Entry<BodyRegionV2, ItemStack> entry : equipped.entrySet()) {
            BodyRegionV2 region = entry.getKey();
            ItemStack stack = entry.getValue();
            if (stack.isEmpty()) continue;

            DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack);
            if (def != null && def.movementStyle() != null) {
                MovementStyle style = def.movementStyle();
                int severity = style.getSeverity();
                int regionOrdinal = region.ordinal();

                if (
                    severity > bestSeverity ||
                    (severity == bestSeverity &&
                        regionOrdinal < bestRegionOrdinal)
                ) {
                    bestStyle = style;
                    MovementModifier mod = def.movementModifier();
                    bestSpeed = (mod != null && mod.speedMultiplier() != null)
                        ? mod.speedMultiplier()
                        : style.getDefaultSpeedMultiplier();
                    bestJumpDisabled = (mod != null &&
                        mod.jumpDisabled() != null)
                        ? mod.jumpDisabled()
                        : style.isDefaultJumpDisabled();
                    bestSeverity = severity;
                    bestRegionOrdinal = regionOrdinal;
                }
            }
        }

        if (bestStyle == null) {
            return ResolvedMovement.NONE;
        }

        return new ResolvedMovement(bestStyle, bestSpeed, bestJumpDisabled);
    }
}
