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

import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
import net.minecraft.core.BlockPos
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.state.BlockState
import net.neoforged.neoforge.capabilities.Capabilities
import net.neoforged.neoforge.items.IItemHandler
import net.neoforged.neoforge.registries.IdMappingEvent
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.registry.game.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(Capabilities.ItemHandler.BLOCK, 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 BuiltInRegistries.ITEM) {
				check(sorted.put(BuiltInRegistries.ITEM.getId(item), ItemStack(item, 1).also { it.count = item.getMaxStackSize(it) }) == null)
			}

			cache.addAll(sorted.values)
			return cache
		}

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