package ru.dbotthepony.mc.otm.block.entity.decorative

import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import net.minecraft.core.BlockPos
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.items.IItemHandler
import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.registries.IdMappingEvent
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.core.getID
import ru.dbotthepony.mc.otm.registry.MBlockEntities

class DevChestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.DEV_CHEST, blockPos, blockState), IItemHandler {
	override fun getSlots(): Int {
		return cache().size
	}

	override fun getStackInSlot(slot: Int): ItemStack {
		return cache().getOrNull(slot) ?: ItemStack.EMPTY
	}

	override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
		return stack
	}

	override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack {
		return getStackInSlot(slot).copyWithCount(amount)
	}

	override fun getSlotLimit(slot: Int): Int {
		return getStackInSlot(slot).maxStackSize
	}

	override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
		return false
	}

	init {
		exposeGlobally(ForgeCapabilities.ITEM_HANDLER, this)
	}

	companion object {
		private val cache = ArrayList<ItemStack>()

		@Suppress("SameReturnValue")
		private fun cache(): List<ItemStack> {
			if (cache.isNotEmpty()) {
				return cache
			}

			val sorted = Int2ObjectAVLTreeMap<ItemStack>()

			for (item in ForgeRegistries.ITEMS.values) {
				check(sorted.put(ForgeRegistries.ITEMS.getID(item), ItemStack(item, 1).also { it.count = item.getMaxStackSize(it) }) == null)
			}

			cache.addAll(sorted.values)
			return cache
		}

		fun mappingsChanged(event: IdMappingEvent) {
			cache.clear()
		}
	}
}
