package ru.dbotthepony.mc.otm.compat.vanilla

import net.minecraft.core.registries.Registries
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.flag.FeatureFlags
import net.minecraft.world.inventory.MenuType
import net.neoforged.bus.api.IEventBus
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.registry.MDeferredRegister

class MatteryChestMenu(
	type: MenuType<*>, containerId: Int,
	inventory: Inventory, val rows: Int, val columns: Int,
	val container: Container = SimpleContainer(rows * columns)
) : MatteryMenu(type, containerId, inventory) {
	val chestSlots = makeSlots(container, ::MatterySlot)
	val sort = SortInput(container, playerSortSettings)

	init {
		require(rows * columns == container.containerSize) { "Provided container $container has different dimensions than specified rows x columns: ${container.containerSize} vs $rows x $columns (${rows * columns})" }
		container.startOpen(player)
		addStorageSlot(chestSlots)
		addInventorySlots()
	}

	override fun stillValid(player: Player): Boolean {
		return container.stillValid(player)
	}

	override fun removed(player: Player) {
		super.removed(player)
		container.stopOpen(player)
	}

	companion object {
		private val registrar = MDeferredRegister(Registries.MENU, OverdriveThatMatters.MOD_ID)

		private val GENERIC_9x1 by registrar.register("generic_9x1") { MenuType(::c9x1, FeatureFlags.VANILLA_SET) }
		private val GENERIC_9x2 by registrar.register("generic_9x2") { MenuType(::c9x2, FeatureFlags.VANILLA_SET) }
		private val GENERIC_9x3 by registrar.register("generic_9x3") { MenuType(::c9x3, FeatureFlags.VANILLA_SET) }
		private val GENERIC_9x4 by registrar.register("generic_9x4") { MenuType(::c9x4, FeatureFlags.VANILLA_SET) }
		private val GENERIC_9x5 by registrar.register("generic_9x5") { MenuType(::c9x5, FeatureFlags.VANILLA_SET) }
		private val GENERIC_9x6 by registrar.register("generic_9x6") { MenuType(::c9x6, FeatureFlags.VANILLA_SET) }
		private val GENERIC_3x3 by registrar.register("generic_3x3") { MenuType(::c3x3, FeatureFlags.VANILLA_SET) }
		private val HOPPER by registrar.register("hopper") { MenuType(::hopper, FeatureFlags.VANILLA_SET) }

		@JvmStatic
		@JvmOverloads
		fun c9x1(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x1, containerId, inventory, 1, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c9x2(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 2)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x2, containerId, inventory, 2, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c9x3(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 3)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x3, containerId, inventory, 3, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c9x4(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 4)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x4, containerId, inventory, 4, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c9x5(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 5)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x5, containerId, inventory, 5, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c9x6(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(9 * 6)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_9x6, containerId, inventory, 6, 9, container)
		}

		@JvmStatic
		@JvmOverloads
		fun c3x3(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(3 * 3)): MatteryChestMenu {
			return MatteryChestMenu(GENERIC_3x3, containerId, inventory, 3, 3, container)
		}

		@JvmStatic
		@JvmOverloads
		fun hopper(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(5)): MatteryChestMenu {
			return MatteryChestMenu(HOPPER, containerId, inventory, 1, 5, container)
		}

		fun register(bus: IEventBus) {
			registrar.register(bus)
			bus.addListener(this::registerScreens)
		}

		private fun registerScreens(event: RegisterMenuScreensEvent) {
			event.register(GENERIC_9x1, ::MatteryChestScreen)
			event.register(GENERIC_9x2, ::MatteryChestScreen)
			event.register(GENERIC_9x3, ::MatteryChestScreen)
			event.register(GENERIC_9x4, ::MatteryChestScreen)
			event.register(GENERIC_9x5, ::MatteryChestScreen)
			event.register(GENERIC_9x6, ::MatteryChestScreen)
			event.register(GENERIC_3x3, ::MatteryChestScreen)
			event.register(HOPPER, ::MatteryChestScreen)
		}
	}
}
