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

import mezz.jei.api.constants.RecipeTypes
import mezz.jei.api.recipe.RecipeType
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.inventory.MenuType
import ru.dbotthepony.mc.otm.block.entity.tech.AbstractPoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredBlastFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredSmokerBlockEntity
import ru.dbotthepony.mc.otm.compat.jei.MicrowaveRecipeCategory
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.menu.OutputSlot
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.game.MMenus
import java.util.function.Supplier

class PoweredFurnaceMenu(
	type: MenuType<PoweredFurnaceMenu>,
	containerID: Int,
	inventory: Inventory,
	tile: AbstractPoweredFurnaceBlockEntity<*, *>? = null
) : AbstractProcessingMachineMenu(type, containerID, inventory, tile) {
	val inputSlots = makeSlots(tile?.inputs ?: SimpleContainer(2), ::MatterySlot)
	val outputSlots = makeSlots(tile?.outputs ?: SimpleContainer(2)) { c, s -> OutputSlot(c, s) { tile?.experience?.popExperience(player as ServerPlayer) } }
	val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }

	override val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
	override val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig, allowPull = true)
	override val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
	override val balanceInputs = BooleanInputWithFeedback(this)
	override val upgrades = makeUpgradeSlots(2, tile?.upgrades)
	override val experience = TakeExperienceWidget(this, tile?.experience)

	override val processingTuples: List<ProcessingTuple> = immutableList(2) {
		ProcessingTuple(inputSlots[it], outputSlots[it], progressGauge[it])
	}

	override val recipeTypes: Supplier<List<RecipeType<*>>>?
		get() {
			return when (type) {
				MMenus.POWERED_FURNACE -> Supplier { listOf(RecipeTypes.SMELTING) }
				MMenus.POWERED_BLAST_FURNACE -> Supplier { listOf(RecipeTypes.BLASTING) }
				MMenus.POWERED_SMOKER -> Supplier { listOf(MicrowaveRecipeCategory.recipeType, RecipeTypes.SMOKING) }
				else -> null
			}
		}

	init {
		if (tile != null) balanceInputs.with(tile::balanceInputs)
		addStorageSlot(inputSlots)
		addStorageSlot(outputSlots)
	}

	companion object {
		fun furnace(
			containerID: Int,
			inventory: Inventory,
			tile: PoweredFurnaceBlockEntity? = null
		) : PoweredFurnaceMenu {
			return PoweredFurnaceMenu(MMenus.POWERED_FURNACE, containerID, inventory, tile)
		}

		fun blasting(
			containerID: Int,
			inventory: Inventory,
			tile: PoweredBlastFurnaceBlockEntity? = null
		) : PoweredFurnaceMenu {
			return PoweredFurnaceMenu(MMenus.POWERED_BLAST_FURNACE, containerID, inventory, tile)
		}

		fun smoking(
			containerID: Int,
			inventory: Inventory,
			tile: PoweredSmokerBlockEntity? = null
		) : PoweredFurnaceMenu {
			return PoweredFurnaceMenu(MMenus.POWERED_SMOKER, containerID, inventory, tile)
		}
	}
}
