package ru.dbotthepony.mc.otm.capability.drive

import net.minecraft.nbt.CompoundTag
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.math.BigInteger
import ru.dbotthepony.mc.otm.core.math.serializeNBT
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.storage.IStorageTuple
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import ru.dbotthepony.mc.otm.storage.StorageStackType
import ru.dbotthepony.mc.otm.storage.key
import java.math.BigInteger
import java.util.*
import kotlin.collections.ArrayList

class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDrive {
	constructor(capacity: BigInteger, max_different_stacks: Int) : super(capacity, maxDifferentStacks = max_different_stacks)
	constructor(capacity: BigInteger, uuid: UUID, max_different_stacks: Int) : super(capacity, uuid, max_different_stacks)
	constructor(capacity: BigInteger, uuid: UUID) : super(capacity, uuid)
	constructor(capacity: BigInteger) : super(capacity)

	override val storageType: StorageStackType<ItemStackWrapper> = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()

	fun insertStack(item: ItemStack, simulate: Boolean): ItemStack {
		return insertStack(ItemStackWrapper(item), simulate).stack
	}

	override fun serializeStack(item: IStorageTuple<ItemStackWrapper>): CompoundTag? {
		val tag = CompoundTag()
		val location = item.stack.registryName.toString()

		tag["item"] = location
		tag["count"] = item.stack.count.serializeNBT()

		val itag = item.stack.item.tag

		if (itag != null) {
			tag["data"] = itag
		}

		return tag
	}

	override fun deserializeStack(tag: CompoundTag): ItemStackWrapper? {
		val item = ForgeRegistries.ITEMS.getValue(ResourceLocation(tag.getString("item")))

		if (item != null && item !== Items.AIR) {
			val count = BigInteger(tag["count"])
			val itemstack = ItemStack(item, 1)
			itemstack.tag = tag["data"] as? CompoundTag
			return ItemStackWrapper(itemstack, copy = false).also { it.count = count }
		}

		return null
	}

	override fun findItems(item: Item): List<IStorageTuple<ItemStackWrapper>> {
		val list = ArrayList<IStorageTuple<ItemStackWrapper>>()

		for ((key, value) in tuples.entries) {
			if (key.item.item === item) {
				list.add(value)
			}
		}

		return list
	}

	override fun findItems(stack: ItemStack): IStorageTuple<ItemStackWrapper>? {
		return tuples[ItemStackWrapper(stack).key()]
	}

	companion object {
		@JvmField
		val DUMMY = ItemMatteryDrive(BigInteger.ZERO, UUID(0L, 0L), 0)
	}
}
