package ru.dbotthepony.mc.otm.registry.objects

import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Item
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockBehaviour
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MRegistry
import java.util.EnumMap
import java.util.function.Supplier

/**
 * Colored only
 */
@Suppress("unused")
open class ColoredDecorativeBlock<B : Block>(
	val baseName: String,
	private val provider: (DyeColor) -> B,
) : IBlockItemRegistryAcceptor {
	var registeredItems = false
		private set

	var registeredBlocks = false
		private set

	protected val itemMap = EnumMap<DyeColor, Supplier<Item>>(DyeColor::class.java)
	protected val blockMap = EnumMap<DyeColor, Supplier<B>>(DyeColor::class.java)

	fun forEachItem(consumer: (String, DyeColor, Item) -> Unit) {
		MRegistry.DYE_ORDER.forEach {
			consumer.invoke(it.name.lowercase(), it, getItem(it))
		}
	}

	fun forEachBlock(consumer: (String, DyeColor, B) -> Unit) {
		MRegistry.DYE_ORDER.forEach {
			consumer.invoke(it.name.lowercase(), it, getBlock(it))
		}
	}

	fun getItem(dyeColor: DyeColor): Item {
		check(registeredItems) { "Didn't register items yet" }
		return itemMap[dyeColor]!!.get()
	}

	fun getBlock(dyeColor: DyeColor): B {
		check(registeredBlocks) { "Didn't register items yet" }
		return blockMap[dyeColor]!!.get()
	}

	val blocks: Map<DyeColor, B> by lazy {
		check(registeredBlocks) { "Didn't register blocks yet" }
		SupplierMap(MRegistry.DYE_ORDER.map { it to blockMap[it]!! })
	}

	val items: Map<DyeColor, Item> by lazy {
		check(registeredItems) { "Didn't register items yet" }
		SupplierMap(MRegistry.DYE_ORDER.map { it to itemMap[it]!! })
	}

	override fun registerBlocks(registry: MDeferredRegister<Block>) {
		check(blockMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" }

		MRegistry.DYE_ORDER.forEach {
			blockMap[it] = registry.register("${baseName}_${it.name.lowercase()}") { provider.invoke(it) }
		}

		registeredBlocks = true
	}

	private val properties = Item.Properties().stacksTo(64)

	override fun registerItems(registry: MDeferredRegister<Item>) {
		check(itemMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" }
		check(registeredBlocks) { "wtffffff???????????" }

		MRegistry.DYE_ORDER.forEach {
			itemMap[it] = registry.register("${baseName}_${it.name.lowercase()}") { BlockItem(blockMap[it]!!.get(), properties) }
		}

		registeredItems = true
	}

	companion object {
		fun simple(baseName: String, provider: (DyeColor) -> BlockBehaviour.Properties): ColoredDecorativeBlock<Block> {
			return ColoredDecorativeBlock(baseName) {
				Block(provider.invoke(it))
			}
		}
	}
}
