package ru.dbotthepony.mc.otm.registry.game

import net.minecraft.client.model.geom.ModelLayers
import net.minecraft.client.renderer.entity.EntityRenderer
import net.minecraft.client.renderer.entity.EntityRenderers
import net.minecraft.client.renderer.entity.MinecartRenderer
import net.minecraft.client.renderer.entity.NoopRenderer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.MobCategory
import net.minecraft.world.item.DyeColor
import net.neoforged.bus.api.IEventBus
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent
import ru.dbotthepony.mc.otm.client.render.entity.BreadMonsterRenderer
import ru.dbotthepony.mc.otm.client.render.entity.LoaderRenderer
import ru.dbotthepony.mc.otm.client.render.entity.PlasmaProjectileRenderer
import ru.dbotthepony.mc.otm.client.render.entity.RogueAndroidRenderer
import ru.dbotthepony.mc.otm.entity.*
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MNames

object MEntityTypes {
	private val registry = MDeferredRegister(BuiltInRegistries.ENTITY_TYPE)

	val PLASMA: EntityType<PlasmaProjectile> by registry.register(MNames.PLASMA) {
		EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA)
	}

	val CARGO_CRATE_MINECARTS: Map<DyeColor?, EntityType<MinecartCargoCrate>> = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color ->
		EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅")
	}

	val RIDEABLE_DUMMY: EntityType<RideableDummy> by registry.register(MNames.RIDEABLE_DUMMY) {
		EntityType.Builder.of({ _, level -> RideableDummy(level) }, MobCategory.MISC)
			.sized(0.5f, 0.5f)
			.passengerAttachments(0.5f)
			.clientTrackingRange(8)
			.build(MNames.RIDEABLE_DUMMY)
	}

	val BREAD_MONSTER: EntityType<BreadMonster> by registry.register(MNames.BREAD_MONSTER) {
		EntityType.Builder.of(::BreadMonster, MobCategory.MONSTER)
			.sized(0.9f, 0.375f)
			.eyeHeight(0.1875f)
			.passengerAttachments(0.375f)
			.clientTrackingRange(8)
			.build(MNames.BREAD_MONSTER)
	}

	val LOADER: EntityType<Loader> by registry.register(MNames.LOADER) {
		EntityType.Builder.of(::Loader, MobCategory.MONSTER)
			.sized(1.2f, 2.5f)
			.eyeHeight(2.0f)
			.passengerAttachments(2.5f)
			.clientTrackingRange(12)
			.build(MNames.LOADER)
	}

	val ANDROID_MELEE: EntityType<AndroidMelee> by registry.register(MNames.ANDROID_MELEE) {
		EntityType.Builder.of(::AndroidMelee, MobCategory.MONSTER)
			.sized(1.2f, 2.5f)
			.eyeHeight(2.0f)
			.passengerAttachments(2.5f)
			.clientTrackingRange(12)
			.build(MNames.ANDROID_MELEE)
	}


	fun register(bus: IEventBus) {
		registry.register(bus)
		bus.addListener(this::registerAttributes)
		bus.addListener(this::registerClient)
	}

	private fun registerAttributes(event: EntityAttributeCreationEvent) {
		event.put(BREAD_MONSTER, BreadMonster.createAttributes().build())
		event.put(LOADER, Loader.createAttributes().build())
		event.put(ANDROID_MELEE, AndroidMelee.createAttributes().build())
	}

	@Suppress("unchecked_cast")
	private fun registerClient(event: FMLClientSetupEvent) {
		event.enqueueWork {
			EntityRenderers.register(PLASMA) { PlasmaProjectileRenderer(it) as EntityRenderer<Entity> }

			for (type in CARGO_CRATE_MINECARTS.values) {
				EntityRenderers.register(type) { MinecartRenderer<MinecartCargoCrate>(it, ModelLayers.CHEST_MINECART) as EntityRenderer<Entity> }
			}

			EntityRenderers.register(RIDEABLE_DUMMY, ::NoopRenderer)
			EntityRenderers.register(BREAD_MONSTER, ::BreadMonsterRenderer)
			EntityRenderers.register(LOADER, ::LoaderRenderer)

			EntityRenderers.register(ANDROID_MELEE) { context ->
				RogueAndroidRenderer(context, ANDROID_MELEE, "melee",context.modelManager)
			}
		}
	}
}
