package ru.dbotthepony.mc.otm.menu.matter

import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage
import ru.dbotthepony.mc.otm.capability.matter.canExtractMatter
import ru.dbotthepony.mc.otm.capability.matter.canReceiveMatter
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus

class MatterBottlerMenu @JvmOverloads constructor(
	p_38852_: Int,
	inventory: Inventory,
	tile: MatterBottlerBlockEntity? = null
) : MatteryPoweredMenu(
	MMenus.MATTER_BOTTLER, p_38852_, inventory, tile
) {
	val workFlow = BooleanInputWithFeedback(this)
	val progressWidget = ProgressGaugeWidget(this)
	val matterWidget = ProfiledLevelGaugeWidget(this, tile?.matter, LevelGaugeWidget(this, tile?.matter))
	val storageSlots: List<MatterySlot>
	val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)

	init {
		val container = tile?.container ?: SimpleContainer(6)

		if (tile != null) {
			progressWidget.with(tile::getWorkProgress)
			workFlow.with(tile::isBottling)
		}

		storageSlots = immutableList(6) { index ->
			object : MatterySlot(container, index) {
				override fun mayPlace(itemStack: ItemStack): Boolean {
					val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: return false

					if (workFlow.value) {
						return index < 3 && cap.canReceiveMatter
					} else {
						return index >= 3 && cap.canExtractMatter
					}
				}
			}
		}

		storageSlots.forEach(this::addStorageSlot)
		addInventorySlots()
	}
}
