package sh.grimmer.bettershulkers.util;

import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.level.block.ShulkerBoxBlock;
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;

import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;

public final class ShulkerBoxHelper {

    private ShulkerBoxHelper() {
    }

    public static NonNullList<ItemStack> getItems(ItemStack stack) {
        NonNullList<ItemStack> items = NonNullList.withSize(ShulkerBoxBlockEntity.CONTAINER_SIZE, ItemStack.EMPTY);
        ItemContainerContents contents = stack.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
        contents.copyInto(items);
        return items;
    }

    @Nullable
    public static Component getCustomName(ItemStack stack) {
        return stack.get(DataComponents.CUSTOM_NAME);
    }

    @Nullable
    public static ItemStack getBulkItem(NonNullList<ItemStack> contents) {
        Map<Item, Integer> itemCounts = new LinkedHashMap<>();
        for (ItemStack itemStack : contents) {
            if (itemStack.isEmpty()) {
                continue;
            }
            itemCounts.merge(itemStack.getItem(), itemStack.getCount(), Integer::sum);
        }
        return itemCounts.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .map(ItemStack::new)
                .orElse(null);
    }

    @Nullable
    public static ItemStack getSingleTypeItem(NonNullList<ItemStack> contents) {
        boolean exactSame = true;
        ItemStack renderItem = null;
        for (ItemStack itemStack : contents) {
            if (itemStack.isEmpty()) {
                continue;
            }
            if (renderItem == null) {
                renderItem = itemStack;
                continue;
            }
            if (exactSame && ItemStack.isSameItemSameComponents(renderItem, itemStack)) {
                continue;
            }
            if (ItemStack.isSameItem(renderItem, itemStack)) {
                exactSame = false;
            } else {
                return null;
            }
        }
        return exactSame ? renderItem : (renderItem != null ? new ItemStack(renderItem.getItem()) : null);
    }

    public static boolean isShulkerBox(ItemStack stack) {
        return stack.getItem() instanceof BlockItem blockItem && blockItem.getBlock() instanceof ShulkerBoxBlock;
    }
}
