package ru.dbotthepony.mc.otm.compat.condensed_creative

import io.wispforest.condensed_creative.entry.impl.CondensedItemEntry
import io.wispforest.condensed_creative.registry.CondensedCreativeInitializer
import io.wispforest.condensed_creative.registry.CondensedEntryRegistry
import net.minecraft.core.RegistryAccess
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.item.CreativeModeTab
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.material.Fluids
import net.neoforged.neoforge.capabilities.Capabilities
import net.neoforged.neoforge.fluids.FluidStack
import net.neoforged.neoforge.fluids.capability.IFluidHandler
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.registry.game.MCreativeTabs
import ru.dbotthepony.mc.otm.registry.game.MItems
import ru.dbotthepony.mc.otm.registry.MRegistry

@CondensedCreativeInitializer.InitializeCondensedEntries
class CondensedCreativeCompat : CondensedCreativeInitializer {
	override fun registerCondensedEntries(refreshed: Boolean, access: RegistryAccess?) {
		addByBase(MItems.TWIN_PLATE_PRESS, MCreativeTabs.MAIN)
		addByBase(MItems.POWERED_FURNACE, MCreativeTabs.MAIN)
		addByBase(MItems.POWERED_BLAST_FURNACE, MCreativeTabs.MAIN)
		addByBase(MItems.POWERED_SMOKER, MCreativeTabs.MAIN)

		addByBase(MItems.ANDROID_STATION, MCreativeTabs.MAIN)
		addByBase(MItems.ANDROID_CHARGER, MCreativeTabs.MAIN)
		addByBase(MItems.BATTERY_BANK, MCreativeTabs.MAIN)
		addByBase(MItems.ENERGY_COUNTER, MCreativeTabs.MAIN)
		addByBase(MItems.CHEMICAL_GENERATOR, MCreativeTabs.MAIN)
		addByBase(MItems.ENERGY_SERVO, MCreativeTabs.MAIN)

		addByBase(MItems.COBBLESTONE_GENERATOR, MCreativeTabs.MAIN)
		addByBase(MItems.ESSENCE_STORAGE, MCreativeTabs.MAIN)

		addByBase(MItems.GRILL, MCreativeTabs.MAIN)

		addByColor(MItems.TRITANIUM_STRIPED_BLOCK, DyeColor.YELLOW, MCreativeTabs.DECORATIVE)
		addByColor(MItems.TRITANIUM_STRIPED_STAIRS, DyeColor.YELLOW, MCreativeTabs.DECORATIVE)
		addByColor(MItems.TRITANIUM_STRIPED_SLAB, DyeColor.YELLOW, MCreativeTabs.DECORATIVE)
		addByColor(MItems.TRITANIUM_STRIPED_WALL, DyeColor.YELLOW, MCreativeTabs.DECORATIVE)

		addByBase(MItems.MATTER_DECOMPOSER, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_CAPACITOR_BANK, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_SCANNER, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_PANEL, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_REPLICATOR, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_BOTTLER, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_RECYCLER, MCreativeTabs.MAIN)
		addByBase(MItems.MATTER_RECONSTRUCTOR, MCreativeTabs.MAIN)

		addByBase(MItems.DRIVE_VIEWER, MCreativeTabs.MAIN)
		addByBase(MItems.ITEM_MONITOR, MCreativeTabs.MAIN)
		addByBase(MItems.STORAGE_POWER_SUPPLIER, MCreativeTabs.MAIN)

		addByFluids(MItems.FLUID_CAPSULE, MCreativeTabs.MAIN)
		addByFluids(MItems.FLUID_TANK, MCreativeTabs.MAIN)

		addByBase(MItems.TRITANIUM_DOOR, MCreativeTabs.DECORATIVE)
		addByBase(MItems.TRITANIUM_TRAPDOOR, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.TRITANIUM_PRESSURE_PLATE.allItems, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.CARGO_CRATES.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MItems.CARGO_CRATE_MINECARTS, MCreativeTabs.DECORATIVE)

		for (anvils in MItems.TRITANIUM_ANVIL.values)
			addByFirst(anvils, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.COMPUTER_TERMINAL.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.STAR_CHAIR.allItems, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.DECORATIVE_CRATE.allItems, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.TRITANIUM_BLOCK.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.TRITANIUM_STAIRS.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.TRITANIUM_SLAB.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.TRITANIUM_WALL.allItems, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.INDUSTRIAL_GLASS.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.INDUSTRIAL_GLASS_PANE.allItems, MCreativeTabs.DECORATIVE)

		addByWhite(MRegistry.UNREFINED_FLOOR_TILES.items, MCreativeTabs.DECORATIVE)
		addByWhite(MRegistry.FLOOR_TILES.items, MCreativeTabs.DECORATIVE)
		addByWhite(MRegistry.FLOOR_TILES_STAIRS.items, MCreativeTabs.DECORATIVE)
		addByWhite(MRegistry.FLOOR_TILES_SLAB.items, MCreativeTabs.DECORATIVE)

		addByBase(MRegistry.VENT.allItems, MCreativeTabs.DECORATIVE)
		addByBase(MRegistry.VENT_ALTERNATIVE.allItems, MCreativeTabs.DECORATIVE)

		addByFirst(MRegistry.TRITANIUM_STRIPED_BLOCK.flatItems, MCreativeTabs.DECORATIVE)
		addByFirst(MRegistry.TRITANIUM_STRIPED_STAIRS.flatItems, MCreativeTabs.DECORATIVE)
		addByFirst(MRegistry.TRITANIUM_STRIPED_SLAB.flatItems, MCreativeTabs.DECORATIVE)
		addByFirst(MRegistry.TRITANIUM_STRIPED_WALL.flatItems, MCreativeTabs.DECORATIVE)
	}

	private fun addByBase(map: Map<DyeColor?, Item>, vararg tabs: CreativeModeTab): CondensedItemEntry.Builder? {
		val base = map[null]

		val builder = CondensedEntryRegistry.fromItems(base!!.registryName, base, map.values)
		tabs.forEach { builder.addToItemGroup(it) }
		return builder
	}

	private fun addByWhite(map: Map<DyeColor, Item>, vararg tabs: CreativeModeTab): CondensedItemEntry.Builder? {
		return addByColor(map, DyeColor.WHITE, *tabs)
	}

	private fun addByColor(map: Map<DyeColor, Item>, color: DyeColor, vararg tabs: CreativeModeTab): CondensedItemEntry.Builder? {
		val base = map[color]

		val builder = CondensedEntryRegistry.fromItems(base!!.registryName, base, map.values)
		tabs.forEach { builder.addToItemGroup(it) }
		return builder
	}

	private fun addByFirst(list: Collection<Item>, vararg tabs: CreativeModeTab): CondensedItemEntry.Builder? {
		val base = list.first()

		val builder = CondensedEntryRegistry.fromItems(base.registryName, base, list)
		tabs.forEach { builder.addToItemGroup(it) }
		return builder
	}

	private fun addByFluids(item: Item, vararg tabs: CreativeModeTab): CondensedItemEntry.Builder? {
		val base = ItemStack(item, 1)

		val list = arrayListOf(base)
		for (fluid in BuiltInRegistries.FLUID) {
			if (fluid != Fluids.EMPTY && fluid.isSource(fluid.defaultFluidState())) {
				list.add(base.copy().also {
					it.getCapability(Capabilities.FluidHandler.ITEM)?.let {
						it.fill(FluidStack(fluid, it.getTankCapacity(0)), IFluidHandler.FluidAction.EXECUTE)
					}
				})
			}
		}

		val builder = CondensedEntryRegistry.fromItemStacks(item.registryName, base, list)
		tabs.forEach { builder.addToItemGroup(it) }
		return builder
	}
}
