package net.halbear.aotg.custom.blocks.Forge;

import io.netty.buffer.Unpooled;
import net.halbear.aotg.registries.ModBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.WorldlyContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import net.neoforged.neoforge.transfer.StacksResourceHandler;
import net.neoforged.neoforge.transfer.item.ItemResource;
import net.neoforged.neoforge.transfer.item.ItemStacksResourceHandler;
import org.jspecify.annotations.Nullable;

import java.util.stream.IntStream;

import static net.halbear.aotg.registries.ModBlockEntities.FORGE_WORKBENCH_BLOCK_ENTITY;

public class ForgeWorkbenchBlockEntity extends RandomizableContainerBlockEntity implements MenuProvider, WorldlyContainer {

    private int ForgeLevel = 0;
    private NonNullList<ItemStack> items = NonNullList.withSize(5, ItemStack.EMPTY);

    public int GetForgeLevel(){return (int)ForgeLevel;}
    public void SetForgeLevel(int BellowPush){this.ForgeLevel = BellowPush ;}

    public ForgeWorkbenchBlockEntity(BlockPos worldPosition, BlockState blockState) {
        super(FORGE_WORKBENCH_BLOCK_ENTITY.get(), worldPosition, blockState);
    }


    public static void tick(Level level, BlockPos pos, BlockState state, ForgeWorkbenchBlockEntity blockEntity) {
        if (level.isClientSide()) return;
        blockEntity.setChanged();
    }

    @Override
    public void loadAdditional(ValueInput input) {
        super.loadAdditional(input);
        if (!this.tryLoadLootTable(input))
            this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
        ContainerHelper.loadAllItems(input, this.items);
        this.ForgeLevel = input.getIntOr("forge_level",0);
    }

    @Override
    public void saveAdditional(ValueOutput output) {
        super.saveAdditional(output);
        output.putInt("forge_level", this.ForgeLevel);
        if (!this.trySaveLootTable(output))
            ContainerHelper.saveAllItems(output, this.items);

    }

    @Override
    public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
        return this.saveWithFullMetadata(registries);
    }

    @Override
    public void handleUpdateTag(ValueInput input) {
        super.handleUpdateTag(input);
    }


    @Override
    public Packet<ClientGamePacketListener> getUpdatePacket() {
        return ClientboundBlockEntityDataPacket.create(this);
    }

    @Override
    public void onDataPacket(Connection connection, ValueInput input) {
        super.onDataPacket(connection, input);
    }

    @Override
    public Component getDisplayName() {
        return Component.translatable("container.ageofthegods.forge");
    }

    @Override
    protected Component getDefaultName() {
        return null;
    }

    @Override
    public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
        return new ForgeWorkbenchGUI(i, inventory, new FriendlyByteBuf(Unpooled.buffer()).writeBlockPos(this.worldPosition));

    }

    @Override
    protected AbstractContainerMenu createMenu(int i, Inventory inventory) {
        return new ForgeWorkbenchGUI(i, inventory, new FriendlyByteBuf(Unpooled.buffer()).writeBlockPos(this.worldPosition));
    }

    private final StacksResourceHandler<ItemStack, ItemResource> resourceHandler = new ItemStacksResourceHandler(this.items) {
        @Override
        protected void onContentsChanged(int index, ItemStack stack) {
            super.onContentsChanged(index, stack);
            setChanged();
        }
    };

    public StacksResourceHandler<ItemStack, ItemResource> getResourceHandler() {
        return this.resourceHandler;
    }


    @Override
    public int getContainerSize() {
        return items.size();
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack itemstack : this.items)
            if (!itemstack.isEmpty())
                return false;
        return true;
    }

    @Override
    protected NonNullList<ItemStack> getItems() {
        return this.items;
    }

    @Override
    protected void setItems(NonNullList<ItemStack> stacks) {
        this.items = stacks;
    }

    @Override
    public boolean canPlaceItem(int index, ItemStack stack) {
        return true;
    }

    @Override
    public int[] getSlotsForFace(Direction side) {
        return IntStream.range(0, this.getContainerSize()).toArray();
    }

    @Override
    public boolean canPlaceItemThroughFace(int index, ItemStack itemstack, @Nullable Direction direction) {
        return this.canPlaceItem(index, itemstack);
    }

    @Override
    public boolean canTakeItemThroughFace(int index, ItemStack itemstack, Direction direction) {
        return true;
    }

    @Override
    public void clearContent() {
        items.clear();
    }
}
