package com.thebrokenrail.gestus.util;

import com.mojang.datafixers.util.Pair;
import com.thebrokenrail.gestus.mixin.EntityAccessor;
import com.thebrokenrail.gestus.mixin.EntityEquipmentUpdateS2CPacketAccessor;
import com.thebrokenrail.gestus.mixin.EntityTrackerUpdateS2CPacketAccessor;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.EntityEquipmentUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;

import java.util.ArrayList;
import java.util.List;

public class Util {
    public static EntityEquipmentUpdateS2CPacket modifyEquipment(EntityEquipmentUpdateS2CPacket packet) {
        List<Pair<EquipmentSlot, ItemStack>> newList = new ArrayList<>();
        for (EquipmentSlot slot : EquipmentSlot.values()) {
            newList.add(Pair.of(slot, ItemStack.EMPTY));
        }
        return new EntityEquipmentUpdateS2CPacket(((EntityEquipmentUpdateS2CPacketAccessor) packet).getId(), newList);
    }

    private static final int INVISIBILITY_FLAG = 5;
    private static final int GLOWING_FLAG = 6;

    private static byte setFlag(byte data, int index, boolean value) {
        if (value) {
            return (byte) (data | 1 << index);
        } else {
            return (byte) (data & ~(1 << index));
        }
    }

    public static EntityTrackerUpdateS2CPacket modifyTracker(PlayerEntity entity, EntityTrackerUpdateS2CPacket packet) {
        TrackedData<Byte> flags = EntityAccessor.getFLAGS();

        List<DataTracker.Entry<?>> newEntries = new ArrayList<>();

        List<DataTracker.Entry<?>> entries = ((EntityTrackerUpdateS2CPacketAccessor) packet).getTrackedValues();
        for (DataTracker.Entry<?> entry : entries) {
            if (entry.getData() == flags) {
                byte data = (Byte) entry.get();
                data = setFlag(data, INVISIBILITY_FLAG, true);
                data = setFlag(data, GLOWING_FLAG, false);
                newEntries.add(new DataTracker.Entry<>(flags, data));
            } else {
                newEntries.add(entry);
            }
        }

        EntityTrackerUpdateS2CPacket newPacket = new EntityTrackerUpdateS2CPacket();
        ((EntityTrackerUpdateS2CPacketAccessor) newPacket).setId(((EntityTrackerUpdateS2CPacketAccessor) packet).getId());
        ((EntityTrackerUpdateS2CPacketAccessor) newPacket).setTrackedValues(newEntries);

        return newPacket;
    }
}
