package ru.dbotthepony.mc.otm.android

import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.core.HolderLookup
import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.nbt.set

abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: MatteryPlayer) : AndroidFeature(type, android) {
	var isActive by syncher.boolean(setter = setter@{ access, value ->
		if (value != access.get()) {
			access.accept(value)

			if (ply is ServerPlayer) {
				if (value) {
					applyModifiers()
				} else {
					removeModifiers()
				}
			}
		}
	})

	open val allowToSwitchByPlayer: Boolean get() = true
	open val allowToSwitchByPlayerWhileSpectator: Boolean get() = true

	open val maxCooldown: Int get() = 0
	open var cooldown by syncher.int()
	val isOnCooldown: Boolean
		get() = maxCooldown > 0 && cooldown > 0

	val cooldownPercent: Float get() {
		if (maxCooldown <= 0) return 0.0f

		if (ply.level() is ClientLevel) {
			return ((cooldown.toFloat() - minecraft.gameRenderer.mainCamera.partialTickTime) / maxCooldown.toFloat()).coerceIn(0.0f, 1.0f)
		}

		return (cooldown.toFloat() / maxCooldown.toFloat()).coerceIn(0.0f, 1.0f)
	}

	fun putOnCooldown() {
		cooldown = maxCooldown
	}

	// TODO: GuiGraphics is stripped from server dist
	// but it doesn't seem to cause issues?
	abstract fun renderIcon(graphics: MGUIGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor = RGBAColor.WHITE)

	override fun serializeNBT(registry: HolderLookup.Provider): CompoundTag {
		return super.serializeNBT(registry).also {
			it["isActive"] = isActive
			it["cooldown"] = cooldown
		}
	}

	override fun deserializeNBT(registry: HolderLookup.Provider, nbt: CompoundTag) {
		super.deserializeNBT(registry, nbt)
		isActive = nbt.getBoolean("isActive")
		cooldown = nbt.getInt("cooldown")
	}

	override fun tickServer() {
		super.tickServer()
		if (cooldown > 0) {
			cooldown--
		}
	}
}
