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.formatMatter
import snownee.jade.api.BlockAccessor
import snownee.jade.api.IBlockComponentProvider
import snownee.jade.api.IServerDataProvider
import snownee.jade.api.ITooltip
import snownee.jade.api.config.IPluginConfig
import snownee.jade.api.ui.BoxStyle
import snownee.jade.api.ui.IElementHelper

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

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

			matterData.putDecimal("storedMatter", it.storedMatter)
			matterData.putDecimal("maxStoredMatter", it.maxStoredMatter)

			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)

				matterData.put("profiledData", profiledData)
			}

			data.put(JadeTagKeys.MATTER_STORAGE_DATA, matterData)
		}
	}

	override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
		val data = accessor.serverData
		if (!data.contains(JadeTagKeys.MATTER_STORAGE_DATA)) return

		val matterData = data.getCompound(JadeTagKeys.MATTER_STORAGE_DATA)
		val storedMatter = matterData.getDecimal("storedMatter")
		val maxStoredMatter = matterData.getDecimal("maxStoredMatter")

		val elementHelper = IElementHelper.get()

		tooltip.add(
			elementHelper.progress(
				storedMatter.percentage(maxStoredMatter),
				TranslatableComponent(
					"otm.gui.level",
					storedMatter.formatMatter(),
					maxStoredMatter.formatMatter()
				),
				elementHelper.progressStyle().color(JadeColors.MATTER_COLOR.toARGB()).textColor(RGBAColor.WHITE.toARGB()),
				BoxStyle.DEFAULT,
				true
			)
		)

		if (matterData.contains("profiledData")) {
			val profiledData = matterData.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.formatMatter().copy().withStyle(ChatFormatting.DARK_GREEN)
		val fb = b.formatMatter().copy().withStyle(ChatFormatting.DARK_RED)

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