package ru.dbotthepony.mc.otm.item

import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.UseOnContext
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity
import ru.dbotthepony.mc.otm.core.TranslatableComponent

class EssenceServoItem : Item(Properties().stacksTo(64)) {
	override fun appendHoverText(pStack: ItemStack, pLevel: Level?, pTooltipComponents: MutableList<Component>, pIsAdvanced: TooltipFlag) {
		super.appendHoverText(pStack, pLevel, pTooltipComponents, pIsAdvanced)
		pTooltipComponents.add(TranslatableComponent("$descriptionId.desc2").withStyle(ChatFormatting.GRAY))
		pTooltipComponents.add(TranslatableComponent("$descriptionId.desc").withStyle(ChatFormatting.DARK_GRAY))
	}

	fun useServo(player: Player, pos: BlockPos): InteractionResult {
		val block = player.level().getBlockEntity(pos) ?: return InteractionResult.FAIL

		// TODO: опыт как жидкость
		if (block is EssenceStorageBlockEntity) {
			if (player.level().isClientSide) return InteractionResult.SUCCESS
			if (player !is ServerPlayer) return InteractionResult.FAIL

			if (player.isCrouching) { // выгружаем в блок
				storeLevel(player, block)
			} else { // выгружаем из блока
				dispenseLevel(player, block)
			}

			return InteractionResult.SUCCESS
		}

		return InteractionResult.FAIL
	}

	override fun useOn(pContext: UseOnContext): InteractionResult {
		val player = pContext.player ?: return InteractionResult.FAIL
		return useServo(player, pContext.clickedPos)
	}

	companion object {
		@JvmStatic
		fun storeLevel(player: ServerPlayer, block: EssenceStorageBlockEntity) {
			val fpoints = (player.experienceProgress * player.xpNeededForNextLevel).toInt()

			if (fpoints > 0) {
				block.experienceStored += fpoints
				player.setExperiencePoints(0)
			} else if (player.experienceLevel > 0) {
				player.setExperienceLevels(player.experienceLevel - 1)
				block.experienceStored += player.xpNeededForNextLevel
				player.setExperiencePoints(0) // для надёжности
			}
		}

		@JvmStatic
		fun dispenseLevel(player: ServerPlayer, block: EssenceStorageBlockEntity) {
			val fpoints = (player.experienceProgress * player.xpNeededForNextLevel).toInt()
			val missingPoints = player.xpNeededForNextLevel - fpoints
			val diff = block.experienceStored.coerceAtMost(missingPoints.toLong()).toInt()

			if (diff == missingPoints) {
				player.setExperienceLevels(player.experienceLevel + 1)
				player.setExperiencePoints(0)
			} else {
				player.setExperiencePoints(fpoints + diff)
			}

			block.experienceStored -= diff
		}
	}
}
