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

import net.minecraft.core.Direction
import kotlin.jvm.JvmOverloads
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
import ru.dbotthepony.mc.otm.block.entity.tech.EnergyCounterBlockEntity
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.registry.MMenus
import java.math.BigDecimal

class EnergyCounterMenu @JvmOverloads constructor(
	p_38852_: Int,
	inventory: Inventory,
	tile: EnergyCounterBlockEntity? = null
) : MatteryMenu(MMenus.ENERGY_COUNTER, p_38852_, inventory, tile) {
	var passed by mSynchronizer.decimal()
	var average by mSynchronizer.decimal()
	var last20Ticks by mSynchronizer.decimal()
	var lastTick by mSynchronizer.decimal()
	var maxIO by mSynchronizer.bigDecimal()

	val switchDirection = oneWayInput {
		if (tile is EnergyCounterBlockEntity)
			tile.level?.setBlock(tile.blockPos, tile.blockState.setValue(EnergyCounterBlock.INPUT_DIRECTION, tile.blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION).opposite), Block.UPDATE_ALL)
	}

	val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java)

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

	var inputDirection by mSynchronizer.enum(Direction::class.java)

	val maxIOInput = bigDecimalInput {
		if (tile is EnergyCounterBlockEntity) {
			if (it.signum() < 0) {
				tile.ioLimit = null
			} else {
				tile.ioLimit = Decimal(it)
			}
		}
	}

	// TODO: Graph and proper networking for it
	private var ticksPassed = 0

	override fun broadcastChanges() {
		if (tile is EnergyCounterBlockEntity) {
			passed = tile.passed
			average = tile.calcAverage(20)
			lastTick = tile.lastTick

			if (ticksPassed == 0) {
				last20Ticks = tile.sumHistory(20)
			}

			ticksPassed = (ticksPassed + 1) % 20
			inputDirection = tile.blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION)

			maxIO = tile.ioLimit?.toBigDecmial() ?: -BigDecimal.ONE
		}

		super.broadcastChanges()
	}

	companion object {
		private val MINUS_ONE = -BigDecimal.ONE
	}
}
