package ru.dbotthepony.mc.otm.compat.jade.providers

import net.minecraft.ChatFormatting
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.compat.jade.JadeColors
import ru.dbotthepony.mc.otm.compat.jade.JadeTagKeys
import ru.dbotthepony.mc.otm.compat.jade.JadeUids
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.getDecimal
import ru.dbotthepony.mc.otm.core.math.putDecimal
import ru.dbotthepony.mc.otm.core.util.formatPower
import snownee.jade.api.*
import snownee.jade.api.config.IPluginConfig
import snownee.jade.api.ui.BoxStyle
import snownee.jade.api.ui.IElementHelper

object MatteryEnergyProvider : IBlockComponentProvider, IServerDataProvider<BlockEntity> {
	override fun getUid(): ResourceLocation = JadeUids.MATTERY_ENERGY

	override fun appendServerData(data: CompoundTag, player: ServerPlayer, level: Level, blockEntity: BlockEntity?, state: Boolean) {
		blockEntity?.getCapability(MatteryCapability.ENERGY)?.ifPresentK {
			val energyData = CompoundTag()

			energyData.putDecimal("batteryLevel", it.batteryLevel)
			energyData.putDecimal("maxBatteryLevel", it.maxBatteryLevel)

			if (it is AbstractProfiledStorage<*>) {
				val profiledData = CompoundTag()

//				profiledData.putDecimal("lastTickReceive", it.lastTickReceive)
//				profiledData.putDecimal("lastTickTransfer", it.lastTickTransfer)

				profiledData.putDecimal("weightedReceive", it.weightedReceive)
				profiledData.putDecimal("weightedTransfer", it.weightedTransfer)

				energyData.put("profiledData", profiledData)
			}

			data.put(JadeTagKeys.MATTERY_ENERGY_DATA, energyData)
		}
	}

	override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
		val data = accessor.serverData

		if (!data.contains(JadeTagKeys.MATTERY_ENERGY_DATA)) return
		val energyData = data.getCompound(JadeTagKeys.MATTERY_ENERGY_DATA)

		val batteryLevel = energyData.getDecimal("batteryLevel")
		val maxBatteryLevel = energyData.getDecimal("maxBatteryLevel")

		val elementHelper = IElementHelper.get()

		tooltip.add(
			elementHelper.progress(
				batteryLevel.percentage(maxBatteryLevel),
				TranslatableComponent(
					"otm.gui.level",
					batteryLevel.formatPower(),
					maxBatteryLevel.formatPower()
				),
				elementHelper.progressStyle().color(JadeColors.ENERGY_COLOR.toARGB(), JadeColors.ENERGY_COLOR2.toARGB()).textColor(RGBAColor.WHITE.toARGB()),
				BoxStyle.DEFAULT,
				true
			)
		)

		if (energyData.contains("profiledData")) {
			val profiledData = energyData.getCompound("profiledData")

			tooltip.add(
				elementHelper.text(
					formatLevel(
						profiledData.getDecimal("weightedReceive"),
						profiledData.getDecimal("weightedTransfer")
					)
				)
			)
		}
	}

	private fun formatLevel(a: Decimal, b: Decimal): Component {
		val diff = a - b

		val fa = a.formatPower().copy().withStyle(ChatFormatting.DARK_GREEN)
		val fb = b.formatPower().copy().withStyle(ChatFormatting.DARK_RED)

		return if (diff.isZero) {
			TranslatableComponent("otm.gui.diff", diff.formatPower().copy().withStyle(ChatFormatting.GRAY), fa, fb)
		} else if (diff.isPositive) {
			TranslatableComponent("otm.gui.diff", diff.formatPower().copy().withStyle(ChatFormatting.DARK_GREEN), fa, fb)
		} else {
			TranslatableComponent("otm.gui.diff", (-diff).formatPower().copy().withStyle(ChatFormatting.DARK_RED), fa, fb)
		}
	}
}
