package com.tiedup.remake.dispenser;

import com.tiedup.remake.items.base.*;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;

/**
 * Generic dispenser behavior for equipping bondage items.
 * Replaces individual BindDispenseBehavior, GagDispenseBehavior, etc.
 *
 * Use factory methods to create instances for each bondage type.
 */
public class GenericBondageDispenseBehavior
    extends EquipBondageDispenseBehavior
{

    private final Class<? extends Item> itemClass;
    private final Predicate<IBondageState> canEquipCheck;
    private final BiConsumer<IBondageState, ItemStack> equipAction;

    private GenericBondageDispenseBehavior(
        Class<? extends Item> itemClass,
        Predicate<IBondageState> canEquipCheck,
        BiConsumer<IBondageState, ItemStack> equipAction
    ) {
        this.itemClass = itemClass;
        this.canEquipCheck = canEquipCheck;
        this.equipAction = equipAction;
    }

    @Override
    protected boolean isValidItem(ItemStack stack) {
        return !stack.isEmpty() && itemClass.isInstance(stack.getItem());
    }

    @Override
    protected boolean canEquip(IBondageState state) {
        return state != null && canEquipCheck.test(state);
    }

    @Override
    protected void equip(IBondageState state, ItemStack stack) {
        if (state != null) {
            equipAction.accept(state, stack);
        }
    }

    // Factory Methods

    public static GenericBondageDispenseBehavior forBind() {
        return new GenericBondageDispenseBehavior(
            ItemBind.class,
            state -> !state.isTiedUp(),
            (s, i) -> s.equip(BodyRegionV2.ARMS, i)
        );
    }

    public static GenericBondageDispenseBehavior forGag() {
        return new GenericBondageDispenseBehavior(
            ItemGag.class,
            state -> !state.isGagged(),
            (s, i) -> s.equip(BodyRegionV2.MOUTH, i)
        );
    }

    public static GenericBondageDispenseBehavior forBlindfold() {
        return new GenericBondageDispenseBehavior(
            ItemBlindfold.class,
            state -> !state.isBlindfolded(),
            (s, i) -> s.equip(BodyRegionV2.EYES, i)
        );
    }

    public static GenericBondageDispenseBehavior forCollar() {
        return new GenericBondageDispenseBehavior(
            ItemCollar.class,
            state -> !state.hasCollar(),
            (s, i) -> s.equip(BodyRegionV2.NECK, i)
        );
    }

    public static GenericBondageDispenseBehavior forEarplugs() {
        return new GenericBondageDispenseBehavior(
            ItemEarplugs.class,
            state -> !state.hasEarplugs(),
            (s, i) -> s.equip(BodyRegionV2.EARS, i)
        );
    }
}
