package ru.dbotthepony.mc.otm.client.screen.storage

import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.NetworkedItemGridPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeBooleanRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeEnumRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.SmallEnumRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.BackgroundPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.asGetterSetter
import ru.dbotthepony.mc.otm.core.util.ItemStorageStackSorter
import ru.dbotthepony.mc.otm.menu.storage.ItemMonitorMenu
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak

@MouseTweaksDisableWheelTweak
class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Component) :
	MatteryScreen<ItemMonitorMenu>(menu, inventory, title) {

	override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
		val frame = FramePanel(this@ItemMonitorScreen, null, 0f, 0f, 1f, 1f, getTitle())

		frame.makeCloseButton()
		frame.onClose { onClose() }

		val topPanel = EditablePanel(this, frame)
		topPanel.height = ITEM_GRID_HEIGHT * 18f
		topPanel.dock = Dock.TOP

		val bottomPanel = EditablePanel(this, frame)
		bottomPanel.height = 3 * 18f
		bottomPanel.dock = Dock.TOP
		bottomPanel.setDockMargin(top = 6f)

		frame.height = topPanel.height + bottomPanel.height + frame.dockPadding.top + frame.dockPadding.bottom + 3f
		frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right

		val controls = DeviceControls(this, frame)

		controls.sortingButtons(menu.settings::ascendingSort.asGetterSetter(), menu.settings::sorting.asGetterSetter(), ItemStorageStackSorter.DEFAULT) {
			for (v in ItemStorageStackSorter.entries) {
				add(v, skinElement = v.icon, tooltip = v.title)
			}
		}

		val grid = NetworkedItemGridPanel(this, topPanel, menu.networkedItemView)
		grid.dock = Dock.FILL

		val craftingGrid = GridPanel(this, bottomPanel, width = 3 * 18f, height = 3 * 18f, columns = 3, rows = 3)
		craftingGrid.dock = Dock.LEFT

		for (i in 0 until 9) {
			SlotPanel(this, craftingGrid, menu.craftingSlots[i])
		}

		val arrowAndButtons = object : EditablePanel<ItemMonitorScreen>(this@ItemMonitorScreen, bottomPanel, width = ProgressGaugePanel.GAUGE_BACKGROUND.width) {
			override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
				ProgressGaugePanel.GAUGE_BACKGROUND.render(graphics, y = height / 2f - ProgressGaugePanel.GAUGE_BACKGROUND.height / 2f)
			}
		}

		arrowAndButtons.dock = Dock.LEFT
		arrowAndButtons.setDockMargin(left = 4f)

		EditablePanel(this, arrowAndButtons, y = 0f, height = 8f, width = arrowAndButtons.width)

		val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width)

		SmallEnumRectangleButtonPanel(this, arrowLine,
			enum = ItemMonitorPlayerSettings.IngredientPriority::class.java,
			prop = menu.settings::ingredientPriority.asGetterSetter(),
			defaultValue = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM)
		.also {
			it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.refill_source.desc"))

			for (setting in ItemMonitorPlayerSettings.IngredientPriority.entries) {
				it.add(setting, setting.icon, setting.component, setting.winding)
			}

			it.dock = Dock.LEFT
		}

		val resultAndButtons = EditablePanel(this, bottomPanel, width = 18f)

		resultAndButtons.dock = Dock.LEFT
		resultAndButtons.setDockMargin(left = 6f)

		SlotPanel(this, resultAndButtons, menu.craftingResult, y = 18f)

		SmallEnumRectangleButtonPanel(this, resultAndButtons, y = 38f,
			enum = ItemMonitorPlayerSettings.ResultTarget::class.java,
			prop = menu.settings::resultTarget.asGetterSetter(),
			defaultValue = ItemMonitorPlayerSettings.ResultTarget.MIXED)
		.also {
			it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.result_target.desc"))

			for (setting in ItemMonitorPlayerSettings.ResultTarget.entries) {
				it.add(setting, setting.icon, setting.component, setting.winding)
			}
		}

		SmallEnumRectangleButtonPanel(this, resultAndButtons, x = 10f, y = 38f,
			enum = ItemMonitorPlayerSettings.Amount::class.java,
			prop = menu.settings::craftingAmount.asGetterSetter(),
			defaultValue = ItemMonitorPlayerSettings.Amount.STACK)
		.also {
			it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.amount.desc"))

			for (setting in ItemMonitorPlayerSettings.Amount.entries) {
				it.add(setting, setting.icon, setting.component, setting.winding)
			}
		}

		val craftingHistory = GridPanel(this, bottomPanel, width = 3 * 18f, height = 3 * 18f, columns = 3, rows = 3)
		craftingHistory.dock = Dock.LEFT
		craftingHistory.setDockMargin(left = 4f)

		val craftingHistoryScroll = DiscreteScrollBarPanel(this, bottomPanel, { 0 }, { _, _, _ -> })
		craftingHistoryScroll.dock = Dock.LEFT
		craftingHistoryScroll.setDockMargin(left = 2f)

		for (i in 0 until 9) {
			object : AbstractSlotPanel<ItemMonitorScreen>(this@ItemMonitorScreen, craftingHistory) {
				override val itemStack: ItemStack get() {
					return ItemStack(Items.ARROW, 42)
				}

				override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
					return craftingHistoryScroll.mouseScrolledInner(x, y, scroll)
				}
			}
		}

		val leftStrip = BackgroundPanel.padded(this, frame, width = AbstractSlotPanel.SIZE, height = 1f)

		BatterySlotPanel(this, leftStrip, menu.batterySlot).also {
			it.dock = Dock.BOTTOM
			leftStrip.height += it.height
		}

		WideProfiledPowerGaugePanel(this, leftStrip, menu.profiledEnergy).also {
			it.dock = Dock.FILL
			it.dockResize = DockResizeMode.NONE
			leftStrip.height += it.height
		}

		leftStrip.height += 3f

		leftStrip.x = -leftStrip.width - 2f
		leftStrip.y = frame.height - leftStrip.height

		return frame
	}

	companion object {
		const val ITEM_GRID_WIDTH = 9
		const val ITEM_GRID_HEIGHT = 5
	}
}
