package com.gregtechceu.gtceu.integration.jade.provider;

import com.gregtechceu.gtceu.api.machine.MetaMachine;
import com.gregtechceu.gtceu.api.machine.trait.MachineTrait;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.entity.BlockEntity;

import lombok.Getter;
import snownee.jade.api.BlockAccessor;
import snownee.jade.api.IBlockComponentProvider;
import snownee.jade.api.IServerDataProvider;
import snownee.jade.api.ITooltip;
import snownee.jade.api.config.IPluginConfig;

import javax.annotation.ParametersAreNonnullByDefault;

/**
 * Jade provider which provides info for a machine trait.
 * 
 * @param <T>       Machine trait class
 * @param <TagType> Info data tag type
 */
@ParametersAreNonnullByDefault
public abstract class MachineTraitProvider<T extends MachineTrait, TagType extends Tag>
                                          implements IBlockComponentProvider, IServerDataProvider<BlockAccessor> {

    @Getter
    private final ResourceLocation uid;
    public final Class<T> traitType;

    protected MachineTraitProvider(ResourceLocation uid, Class<T> type) {
        this.uid = uid;
        this.traitType = type;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void appendTooltip(ITooltip iTooltip, BlockAccessor block, IPluginConfig iPluginConfig) {
        var be = block.getBlockEntity();
        if (be == null || !block.getServerData().contains(uid.toString(), CompoundTag.TAG_COMPOUND)) return;

        var serverData = block.getServerData().getCompound(uid.toString());
        addTooltip((TagType) serverData, iTooltip, block.getPlayer(), block, be, iPluginConfig);
    }

    @Override
    public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) {
        var be = blockAccessor.getBlockEntity();
        if (be instanceof MetaMachine machine) {
            T t = machine.getTrait(traitType);
            if (t != null) compoundTag.put(uid.toString(), write(t));
        }
    }

    protected abstract TagType write(T trait);

    protected abstract void addTooltip(TagType data, ITooltip tooltip, Player player, BlockAccessor block,
                                       BlockEntity blockEntity, IPluginConfig config);
}
