package ru.dbotthepony.mc.otm.block.decorative

import net.minecraft.core.BlockPos
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.util.StringRepresentable
import net.minecraft.world.item.DyeColor
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.EnumProperty
import net.minecraft.world.level.material.MapColor
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.decorative.GrillBlockEntity
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.math.component1
import ru.dbotthepony.mc.otm.core.math.component2
import ru.dbotthepony.mc.otm.core.math.component3
import kotlin.math.absoluteValue

class GrillBlock(val color: DyeColor?) : RotatableMatteryBlock(Properties.of().mapColor(color?.mapColor ?: MapColor.METAL).destroyTime(0.75f).explosionResistance(10.0f)), EntityBlock {
	override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity {
		return GrillBlockEntity(p_153215_, p_153216_)
	}

	init {
		tooltips.colored(color)
	}

	override fun <T : BlockEntity?> getTicker(
		p_153212_: Level,
		p_153213_: BlockState,
		p_153214_: BlockEntityType<T>
	): BlockEntityTicker<T>? {
		if (p_153212_.isClientSide)
			return null

		return BlockEntityTicker { _, _, _, t -> if (t is GrillBlockEntity) t.tick() }
	}

	enum class State : StringRepresentable {
		IDLE,
		FUELED,
		GRILLING;

		private val str = name.lowercase()

		override fun getSerializedName(): String {
			return str
		}
	}

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

	override fun animateTick(blockState: BlockState, level: Level, blockPos: BlockPos, random: RandomSource) {
		val state = blockState[STATE_PROPERTY]

		if (state === State.IDLE)
			return

		val (x, y, z) = blockPos

		if (random.nextInt(15) == 0) {
			val xd = x + 0.5 + random.nextGaussian() * 0.1
			val yd = y + 1.1
			val zd = z + 0.5 + random.nextGaussian() * 0.1

			level.addParticle(ParticleTypes.LAVA, xd, yd, zd, random.nextDouble() * 0.5, 0.005, random.nextDouble() * 0.5)
		}

		if (random.nextInt(6) == 0) {
			level.playLocalSound(
				x + 0.5,
				y + 0.5,
				z + 0.5,
				SoundEvents.CAMPFIRE_CRACKLE,
				SoundSource.BLOCKS,
				0.5f + random.nextFloat(),
				random.nextFloat() * 0.7f + 0.6f,
				false
			)
		}

		if (state === State.GRILLING && random.nextInt(4) == 0) {
			val xd = x + 0.5 + random.nextGaussian() * 0.25
			val yd = y + 1.1
			val zd = z + 0.5 + random.nextGaussian() * 0.25

			level.addParticle(ParticleTypes.CAMPFIRE_COSY_SMOKE, xd, yd, zd, 0.0, random.nextGaussian().absoluteValue * 0.04 + 0.02, 0.0)
		}
	}

	companion object {
		val STATE_PROPERTY: EnumProperty<State> = EnumProperty.create("state", State::class.java)
	}
}
