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

import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.capability.energy.ItemEnergyStorageImpl
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.nbt.map

abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(p_155228_, p_155229_, p_155230_) {
	val batteryContainer = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
	val batteryItemHandler = batteryContainer.handler(HandlerFilter.Dischargeable)

	init {
		savetables.stateful(::batteryContainer, BATTERY_KEY)
	}

	override fun tick() {
		super.tick()

		val energy = matteryEnergy
		if (energy == null || batteryContainer.isEmpty)
			return

		var demand = energy.receiveEnergy(energy.missingPower, true)
		if (demand.isZero) return

		for (stack in batteryContainer) {
			if (!stack.isEmpty) {
				stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
					val diff = it.extractEnergy(demand, false)
					energy.receiveEnergy(diff, false)
					demand -= diff
				}

				if (demand <= Decimal.ZERO)
					return
			}
		}
	}

	companion object {
		fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
			val tag = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return
			val container = MatteryContainer(1)
			tag.map(BATTERY_KEY, container::deserializeNBT)

			if (!container[0].isEmpty) {
				tooltips.add(TranslatableComponent("otm.item.block.stored_battery", container[0].displayName).withStyle(ChatFormatting.GRAY))

				ItemEnergyStorageImpl.appendHoverText(container[0], tooltips)
			}
		}
	}
}
