package ru.dbotthepony.mc.otm.block.tech

import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.nbt.LongTag
import net.minecraft.world.InteractionHand
import net.minecraft.world.ItemInteractionResult
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
import net.neoforged.neoforge.fluids.FluidUtil
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.addSimpleDescription
import ru.dbotthepony.mc.otm.block.entity.tech.EssenceStorageBlockEntity
import ru.dbotthepony.mc.otm.block.getShapeForEachState
import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
import ru.dbotthepony.mc.otm.item.EssenceServoItem
import ru.dbotthepony.mc.otm.registry.game.MItems
import ru.dbotthepony.mc.otm.shapes.BlockShapes

class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properties.of().mapColor(color?.mapColor ?: MapColor.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().destroyTime(1.5f).explosionResistance(60.0f)), EntityBlock {
	init {
		tooltips.painted(color)

		addSimpleDescription()

		tooltips.blockEntityData<LongTag>("experienceStored") { _, _, l, acceptor ->
			if (minecraft.window.isShiftDown) {
				acceptor(TranslatableComponent("otm.gui.experience", l.asLong).withStyle(ChatFormatting.GRAY))
			} else {
				acceptor(TranslatableComponent("otm.gui.experience_levels", getLevelFromXp(l.asLong)).withStyle(ChatFormatting.GRAY))
			}
		}

		registerDefaultState(getStateDefinition().any().setValue(FILLED, false))
	}

	override fun newBlockEntity(pPos: BlockPos, pState: BlockState): BlockEntity {
		return EssenceStorageBlockEntity(pPos, pState)
	}

	override fun <T : BlockEntity?> getTicker(pLevel: Level, pState: BlockState, pBlockEntityType: BlockEntityType<T>): BlockEntityTicker<T>? {
		if (!pLevel.isClientSide) {
			return BlockEntityTicker { _, _, _, pBlockEntity -> if (pBlockEntity is EssenceStorageBlockEntity) pBlockEntity.tick() }
		}

		return null
	}

	override fun useItemOn(itemStack: ItemStack, blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, hand: InteractionHand, blockHitResult: BlockHitResult): ItemInteractionResult {
		if (itemStack.item is EssenceServoItem) {
			return (itemStack.item as EssenceServoItem).useServo(ply, blockPos)
		}

		if (FluidUtil.interactWithFluidHandler(ply, hand, level, blockPos, blockHitResult.direction)) {
			return ItemInteractionResult.sidedSuccess(level.isClientSide)
		}

		return super.useItemOn(itemStack, blockState, level, blockPos, ply, hand, blockHitResult)
	}

	override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
		super.createBlockStateDefinition(builder)
		builder.add(FILLED)
	}

	private val shapes = getShapeForEachState(rotationProperty) { BlockShapes.ESSENCE_STORAGE.rotateFromNorth(it[rotationProperty]).computeShape() }

	@Suppress("override_deprecation")
	override fun getShape(
		state: BlockState,
		blockGetter: BlockGetter,
		pos: BlockPos,
		context: CollisionContext
	): VoxelShape {
		return shapes[state]!!
	}

	companion object {
		val FILLED = BooleanProperty.create("filled")
	}
}
