package ru.dbotthepony.mc.otm.core.collect

import net.minecraft.world.Container
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse
import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.get

/**
 * Allows to see the contents of container and extract the item from it
 */
interface AwareItemStack {
	operator fun component0(): ItemStack
	val itemStack: ItemStack get() = component0()

	/**
	 * Extracts item from underlying container
	 */
	fun extract(amount: Int, simulate: Boolean = true): ItemStack
}

data class ContainerItemStackEntry(val index: Int, val container: Container) : AwareItemStack {
	override fun component0(): ItemStack {
		return container[index]
	}

	override fun extract(amount: Int, simulate: Boolean): ItemStack {
		if (container is Inventory && index in 36 .. 39 && hasBindingCurse(container[index])) {
			return ItemStack.EMPTY
		}

		if (simulate) {
			return container[index].let { if (it.isEmpty) it else it.copy().also { it.count = it.count.coerceAtMost(amount) } }
		}

		val item = container[index]
		val newCount = (item.count - amount).coerceAtLeast(0)

		if (newCount == 0) {
			container[index] = ItemStack.EMPTY
			return item
		}

		val copy = item.copy().also { it.count = amount }
		container[index] = item.copy().also { it.count -= amount }
		return copy
	}
}

data class ItemHandlerItemStackEntry(val index: Int, val handler: IItemHandler) : AwareItemStack {
	override fun component0(): ItemStack {
		return handler[index]
	}

	override fun extract(amount: Int, simulate: Boolean): ItemStack {
		return handler.extractItem(index, amount, simulate)
	}
}
