package top.r3944realms.lib39.core.sync;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

/**
 * The interface Lib 39 sync data holder.
 */
public interface ILib39SyncDataHolder {
    /**
     * Lib 39 get sync data compound tag.
     *
     * @return the compound tag
     */
    CompoundTag lib39$getSyncData();

    /**
     * Lib 39 set sync data.
     *
     * @param tag the tag
     */
    void lib39$setSyncData(CompoundTag tag);

    /**
     * Lib 39 inject save sync data compound tag.
     *
     * @param output the tag
     */
    default void lib39$injectSaveSyncData(ValueOutput output) {
        if (lib39$getSyncData() != null && !lib39$getSyncData().isEmpty()) {
            output.store("Lib39Data", CompoundTag.CODEC, lib39$getSyncData());
        }
    }

    /**
     * Lib 39 inject load sync data.
     *
     * @param input the input
     */
    default void lib39$injectLoadSyncData(@NotNull ValueInput input) {
        Optional<ValueInput> lib39DataOpt = input.child("Lib39Data");
        if (lib39DataOpt.isPresent()) {
            ValueInput valueInput = lib39DataOpt.get();
            Optional<CompoundTag> lib39Data = valueInput.read("Lib39Data", CompoundTag.CODEC);
            lib39$setSyncData(lib39Data.get());
        }
    }

    /**
     * Save sync data.
     *
     * @param syncData the sync data
     */
    default void saveSyncData(@NotNull NBTEntitySyncData syncData) {
        lib39$getSyncData().put(syncData.id.toDebugFileName(), syncData.serializeNBT());
    }

    /**
     * Load sync data.
     *
     * @param syncData the sync data
     */
    default void loadSyncData(NBTEntitySyncData syncData) {
        if (syncData != null && lib39$getSyncData().contains(syncData.id.toDebugFileName())) {
            Optional<CompoundTag> compound = lib39$getSyncData().getCompound(syncData.id.toDebugFileName());
            if (compound.isPresent()) {
                syncData.deserializeNBT(compound.get());
            }
        }
    }

    /**
     * Gets holder.
     *
     * @param entity the entity
     * @return the holder
     */
    static ILib39SyncDataHolder getHolder(Entity entity) {
        return (ILib39SyncDataHolder) entity;
    }
}
