package com.gregtechceu.gtceu.api.transfer.item;

import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.items.ItemStackHandler;

import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;

import java.util.function.Predicate;

public class CustomItemStackHandler extends ItemStackHandler
                                    implements INBTSerializable<CompoundTag> {

    @Getter
    @Setter
    protected @NotNull Runnable onContentsChanged = () -> {};
    @Getter
    @Setter
    protected Predicate<ItemStack> filter = stack -> true;

    public CustomItemStackHandler() {
        super();
    }

    public CustomItemStackHandler(int size) {
        super(size);
    }

    public CustomItemStackHandler(ItemStack itemStack) {
        this(NonNullList.of(ItemStack.EMPTY, itemStack));
    }

    public CustomItemStackHandler(NonNullList<ItemStack> stacks) {
        super(stacks);
    }

    @Override
    public boolean isItemValid(int slot, @NotNull ItemStack stack) {
        return filter.test(stack);
    }

    @Override
    public void onContentsChanged(int slot) {
        onContentsChanged.run();
    }

    public void clear() {
        stacks.clear();
        onContentsChanged.run();
    }

    public NonNullList<ItemStack> toList() {
        NonNullList<ItemStack> list = NonNullList.create();
        for (int slot = 0; slot < getSlots(); slot++) list.add(getStackInSlot(slot));
        return list;
    }

    public void dropInventoryInWorld(Level world, BlockPos pos) {
        for (ItemStack stack : stacks) {
            Block.popResource(world, pos, stack);
        }
        clear();
    }

    @Override
    public void deserializeNBT(CompoundTag nbt) {
        if (nbt.getInt("Size") != stacks.size()) nbt.putInt("Size", stacks.size());
        super.deserializeNBT(nbt);
    }
}
