package ru.dbotthepony.mc.otm.block.entity.storage

import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.graph.storage.StorageNode
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.storage.DriveRackMenu
import ru.dbotthepony.mc.otm.graph.storage.StorageGraph
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.storage.*

class DriveRackBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
	MatteryPoweredBlockEntity(MBlockEntities.DRIVE_RACK, p_155229_, p_155230_) {
	val energy = WorkerEnergyStorage(this, MachinesConfig.DRIVE_RACK)

	val container: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
		override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
			super.setChanged(slot, new, old)

			old.getCapability(MatteryCapability.DRIVE).ifPresent {
				cell.computeIfAbsent(it.storageType) {
					PoweredVirtualComponent(it, energy)
				}.remove(it)
			}

			new.getCapability(MatteryCapability.DRIVE).ifPresent {
				cell.computeIfAbsent(it.storageType) {
					PoweredVirtualComponent(it, energy)
				}.add(it)
			}
		}
	}.also(::addDroppableContainer)

	val cell = StorageNode(energy)

	init {
		savetable(::energy, ENERGY_KEY)
		savetable(::container, INVENTORY_KEY)
		exposeEnergyGlobally(energy)
		exposeGlobally(MatteryCapability.STORAGE_NODE, cell)
	}

	override fun setLevel(level: Level) {
		super.setLevel(level)
		cell.discover(this)
	}

	override fun tick() {
		super.tick()
		cell.tickEnergyDemanding()
	}

	override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
		return DriveRackMenu(containerID, inventory, this)
	}

	override fun setRemoved() {
		super.setRemoved()
		cell.isValid = false
	}
}
