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

import com.tiedup.remake.items.ItemKey;
import com.tiedup.remake.items.ModItems;
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 unlocks their own equipped item using the matching key.
 */
public class PacketV2SelfUnlock {

    private final BodyRegionV2 region;

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

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

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

    public static void handle(
        PacketV2SelfUnlock 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-unlock (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.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 matching key in inventory
            UUID lockedByUUID = lockable.getLockedByKeyUUID(equipped);
            ItemStack keyStack = findMatchingKeyInInventory(
                player,
                lockedByUUID
            );
            if (keyStack.isEmpty()) return;

            lockable.setLockedByKeyUUID(equipped, null);
            V2EquipmentHelper.sync(player);
        });
        ctx.setPacketHandled(true);
    }

    /**
     * Find a key in the player's inventory that matches the lock UUID,
     * or a master key that unlocks anything.
     */
    private static ItemStack findMatchingKeyInInventory(
        ServerPlayer player,
        UUID lockedByUUID
    ) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack s = player.getInventory().getItem(i);
            if (s.isEmpty()) continue;
            // Master key unlocks everything
            if (s.is(ModItems.MASTER_KEY.get())) return s;
            // Regular key: must match the lock UUID
            if (s.getItem() instanceof ItemKey key) {
                if (
                    lockedByUUID != null &&
                    lockedByUUID.equals(key.getKeyUUID(s))
                ) {
                    return s;
                }
            }
        }
        return ItemStack.EMPTY;
    }
}
