package ru.dbotthepony.mc.otm.menu.tech

import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.core.util.getTotalXpRequiredForLevel
import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem
import ru.dbotthepony.mc.otm.item.EssenceServoItem
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.registry.MItems
import ru.dbotthepony.mc.otm.registry.MMenus

class EssenceStorageMenu @JvmOverloads constructor(
	containerID: Int,
	inventory: Inventory,
	tile: EssenceStorageBlockEntity? = null
) : MatteryMenu(MMenus.ESSENCE_STORAGE, containerID, inventory, tile) {
	val experienceStored by mSynchronizer.ComputedLongField(getter = { tile?.experienceStored ?: 0L }).property
	val redstoneConfig = EnumInputWithFeedback<RedstoneSetting>(this)
	val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig)

	val capsuleSlot = object : MatterySlot(tile?.capsuleContainer ?: SimpleContainer(1), 0) {
		override fun mayPlace(itemStack: ItemStack): Boolean {
			return itemStack.item is EssenceCapsuleItem && super.mayPlace(itemStack)
		}
	}

	val servoSlot = object : MatterySlot(tile?.servoContainer ?: SimpleContainer(1), 0) {
		override fun mayPlace(itemStack: ItemStack): Boolean {
			return itemStack.item == MItems.ESSENCE_SERVO && super.mayPlace(itemStack)
		}
	}

	val storeLevels = intInput {
		if (it > 0) {
			val ply = ply as ServerPlayer
			tile!!

			if (it == 1) {
				EssenceServoItem.storeLevel(ply, tile)
			} else {
				if (ply.experienceProgress > 0f) {
					EssenceServoItem.storeLevel(ply, tile)
				}

				if (ply.experienceLevel > 0) {
					val old = ply.experienceLevel
					val new = (old - it).coerceAtLeast(0)

					tile.experienceStored += getTotalXpRequiredForLevel(old) - getTotalXpRequiredForLevel(new)
					ply.setExperienceLevels(new)
				}
			}
		}
	}

	val dispenseLevels = intInput {
		if (it > 0) {
			val ply = ply as ServerPlayer
			tile!!

			if (it == 1) {
				EssenceServoItem.dispenseLevel(ply, tile)
			} else {
				var i = 0

				while (i++ < it && tile.experienceStored > 0L) {
					EssenceServoItem.dispenseLevel(ply, tile)
				}
			}
		}
	}

	init {
		storeLevels.filter {
			it.isCreative || it.matteryPlayer?.isAndroid == true || servoSlot.item.item == MItems.ESSENCE_SERVO //|| it.itemsStream(true).anyMatch { it.item == MItems.ESSENCE_SERVO }
		}

		storeLevels.filter {
			it.experienceProgress > 0f || it.experienceLevel > 0
		}

		dispenseLevels.filter {
			it.isCreative || it.matteryPlayer?.isAndroid == true || servoSlot.item.item == MItems.ESSENCE_SERVO //|| it.itemsStream(true).anyMatch { it.item == MItems.ESSENCE_SERVO }
		}

		dispenseLevels.filter { (tile?.experienceStored ?: experienceStored) > 0L }

		if (tile != null) {
			redstoneConfig.with(tile.redstoneControl::redstoneSetting)
		}

		addStorageSlot(capsuleSlot)
		addStorageSlot(servoSlot)
		addInventorySlots()
	}
}
