package top.r3944realms.lib39.mixin;

import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.sync.ILib39SyncDataHolder;
import top.r3944realms.lib39.core.sync.ISyncData;
import top.r3944realms.lib39.core.sync.NBTEntitySyncData;

import java.util.UUID;

/**
 * The type Mixin entity.
 */
@Mixin(Entity.class)
public abstract class MixinEntity implements ILib39SyncDataHolder {
    /**
     * Gets uuid.
     *
     * @return the uuid
     */
    @Shadow public abstract UUID getUUID();

    @Unique
    private CompoundTag lib39$syncData;

    @Override
    public CompoundTag lib39$getSyncData() {
        if (lib39$syncData == null) {
            lib39$syncData = new CompoundTag();
        }
        return lib39$syncData;
    }

    @Override
    public void lib39$setSyncData(CompoundTag tag) {
        this.lib39$syncData = tag;
    }

    @WrapMethod(method = "saveWithoutId")
    private CompoundTag wrapSave(CompoundTag compound, @NotNull Operation<CompoundTag> original) {
        FabricCommonEventHandler.getSyncData2Manager().forEach((id, manager) -> {
            ISyncData<?> o = manager.getSyncMap().get(getUUID());
            if (o instanceof NBTEntitySyncData syncData) {
                saveSyncData(syncData);
            }
        });
        return lib39$injectSaveSyncData(original.call(compound));
    }

    @WrapMethod(method = "load")
    private void warpLoad(CompoundTag compound, @NotNull Operation<Void> original) {
       original.call(compound);
       lib39$injectLoadSyncData(compound);
    }
}
