package ru.dbotthepony.mc.otm.network

import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.codec.StreamCodec
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.util.RandomSource
import net.minecraft.world.level.Level
import net.neoforged.neoforge.network.PacketDistributor
import net.neoforged.neoforge.network.handling.IPayloadContext
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.otmRandom

class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : CustomPacketPayload {
	fun write(buff: FriendlyByteBuf) {
		buff.writeDouble(x)
		buff.writeDouble(y)
		buff.writeDouble(z)
	}

	fun play(context: IPayloadContext) {
		minecraft.player?.level()?.let {
			makeSmoke(x, y, z, it.otmRandom, it)
		}
	}

	override fun type(): CustomPacketPayload.Type<out CustomPacketPayload> {
		return TYPE
	}

	companion object {
		val TYPE =
			CustomPacketPayload.Type<SmokeParticlesPacket>(ResourceLocation(OverdriveThatMatters.MOD_ID, "smoke"))
		val CODEC: StreamCodec<FriendlyByteBuf, SmokeParticlesPacket> =
			StreamCodec.ofMember(SmokeParticlesPacket::write, ::read)

		fun read(buff: FriendlyByteBuf): SmokeParticlesPacket {
			return SmokeParticlesPacket(buff.readDouble(), buff.readDouble(), buff.readDouble())
		}

		fun makeSmoke(x: Double, y: Double, z: Double, level: ServerLevel) {
			PacketDistributor.sendToPlayersNear(level, null, x, y, z, 64.0, SmokeParticlesPacket(x, y, z))
		}

		fun makeSmoke(excluded: ServerPlayer, x: Double, y: Double, z: Double) {
			PacketDistributor.sendToPlayersNear(excluded.serverLevel(), excluded, x, y, z, 64.0, SmokeParticlesPacket(x, y, z))
		}

		fun makeSmoke(x: Double, y: Double, z: Double, random: RandomSource, level: Level) {
			for (i in 0 .. random.nextInt(4, 8))
				level.addParticle(ParticleTypes.POOF, x + random.nextDouble() * 0.5 - 0.25, y + random.nextDouble() * 0.5 - 0.25, z + random.nextDouble() * 0.5 - 0.25, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02, random.nextGaussian() * 0.02)
		}
	}
}
