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

import com.tiedup.remake.v2.bondage.IV2EquipmentHolder;
import com.tiedup.remake.v2.bondage.capability.V2BondageEquipmentProvider;
import java.util.function.Supplier;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.network.NetworkEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Server-to-client packet that syncs V2 bondage equipment state.
 *
 * Sent when equipment changes (equip/unequip/clear) and on player login
 * or start-tracking. The client deserializes into its local capability
 * so the render layer has data to display.
 */
public class PacketSyncV2Equipment {

    private static final Logger LOGGER = LogManager.getLogger(
        "PacketSyncV2Equipment"
    );

    private final int entityId;
    private final CompoundTag data;

    public PacketSyncV2Equipment(int entityId, CompoundTag data) {
        this.entityId = entityId;
        this.data = data != null ? data : new CompoundTag();
    }

    // ==================== Codec ====================

    public static void encode(PacketSyncV2Equipment msg, FriendlyByteBuf buf) {
        buf.writeInt(msg.entityId);
        buf.writeNbt(msg.data);
    }

    public static PacketSyncV2Equipment decode(FriendlyByteBuf buf) {
        int entityId = buf.readInt();
        CompoundTag data = buf.readNbt();
        return new PacketSyncV2Equipment(
            entityId,
            data != null ? data : new CompoundTag()
        );
    }

    // ==================== Handler ====================

    public static void handle(
        PacketSyncV2Equipment msg,
        Supplier<NetworkEvent.Context> ctxSupplier
    ) {
        NetworkEvent.Context ctx = ctxSupplier.get();
        ctx.enqueueWork(() -> {
            if (FMLEnvironment.dist == Dist.CLIENT) {
                handleOnClient(msg);
            }
        });
        ctx.setPacketHandled(true);
    }

    @OnlyIn(Dist.CLIENT)
    private static void handleOnClient(PacketSyncV2Equipment msg) {
        Level level = Minecraft.getInstance().level;
        if (level == null) return;

        Entity entity = level.getEntity(msg.entityId);
        if (entity instanceof LivingEntity living) {
            // IV2EquipmentHolder entities (Damsels, NPCs) use SynchedEntityData
            // for equipment sync, not this packet — both V2EquipmentHelper.sync
            // and syncTo short-circuit on holders. If a packet for a holder
            // does arrive it's a protocol bug; drop it rather than race with
            // the EntityData path.
            if (living instanceof IV2EquipmentHolder) {
                return;
            }
            living
                .getCapability(V2BondageEquipmentProvider.V2_BONDAGE_EQUIPMENT)
                .ifPresent(equip -> equip.deserializeNBT(msg.data));
        }
    }
}
