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

import com.tiedup.remake.items.ItemKey;
import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.network.PacketRateLimiter;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import java.util.UUID;
import java.util.function.Supplier;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.NetworkEvent;

/**
 * Client→Server: Player locks their own equipped item using a key from inventory.
 */
public class PacketV2SelfLock {

    private final BodyRegionV2 region;

    public PacketV2SelfLock(BodyRegionV2 region) {
        this.region = region;
    }

    public static void encode(PacketV2SelfLock msg, FriendlyByteBuf buf) {
        buf.writeEnum(msg.region);
    }

    public static PacketV2SelfLock decode(FriendlyByteBuf buf) {
        return new PacketV2SelfLock(buf.readEnum(BodyRegionV2.class));
    }

    public static void handle(
        PacketV2SelfLock msg,
        Supplier<NetworkEvent.Context> ctxSupplier
    ) {
        NetworkEvent.Context ctx = ctxSupplier.get();
        ctx.enqueueWork(() -> {
            ServerPlayer player = ctx.getSender();
            if (player == null) return;
            if (!PacketRateLimiter.allowPacket(player, "action")) return;

            // Arms and hands must be free to self-lock (RISK-006: mittens bypass)
            if (
                V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.ARMS) ||
                V2EquipmentHelper.isRegionOccupied(player, BodyRegionV2.HANDS)
            ) return;

            ItemStack equipped = V2EquipmentHelper.getInRegion(
                player,
                msg.region
            );
            if (equipped.isEmpty()) return;
            if (!(equipped.getItem() instanceof ILockable lockable)) return;
            if (
                !lockable.isLockable(equipped) || lockable.isLocked(equipped)
            ) return;

            // Furniture seat blocks this region
            if (
                player.isPassenger() &&
                player.getVehicle() instanceof
                    com.tiedup.remake.v2.furniture.ISeatProvider provider
            ) {
                com.tiedup.remake.v2.furniture.SeatDefinition seat =
                    provider.getSeatForPassenger(player);
                if (
                    seat != null && seat.blockedRegions().contains(msg.region)
                ) {
                    return; // Region blocked by furniture
                }
            }

            // Find a key in inventory
            ItemStack keyStack = findKeyInInventory(player);
            if (keyStack.isEmpty()) return;
            if (!(keyStack.getItem() instanceof ItemKey key)) return;

            UUID keyUUID = key.getKeyUUID(keyStack);
            lockable.setLockedByKeyUUID(equipped, keyUUID);
            V2EquipmentHelper.sync(player);
        });
        ctx.setPacketHandled(true);
    }

    /** Find the first ItemKey in the player's inventory. Returns ItemStack.EMPTY if none. */
    private static ItemStack findKeyInInventory(ServerPlayer player) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack s = player.getInventory().getItem(i);
            if (!s.isEmpty() && s.getItem() instanceof ItemKey) {
                return s;
            }
        }
        return ItemStack.EMPTY;
    }
}
