package mezz.jei.input;

import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.gui.GuiScreenHelper;
import mezz.jei.ingredients.RegisteredIngredients;

import mezz.jei.ingredients.TypedIngredient;
import mezz.jei.util.ImmutableRect2i;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;

import java.util.Optional;
import java.util.stream.Stream;

public class GuiContainerWrapper implements IRecipeFocusSource {
	private final RegisteredIngredients registeredIngredients;
	private final GuiScreenHelper guiScreenHelper;

	public GuiContainerWrapper(RegisteredIngredients registeredIngredients, GuiScreenHelper guiScreenHelper) {
		this.registeredIngredients = registeredIngredients;
		this.guiScreenHelper = guiScreenHelper;
	}

	@Override
	public Stream<IClickedIngredient<?>> getIngredientUnderMouse(double mouseX, double mouseY) {
		Screen guiScreen = Minecraft.getInstance().screen;
		if (!(guiScreen instanceof AbstractContainerScreen<?> guiContainer)) {
			return Stream.empty();
		}
		return Stream.concat(
			guiScreenHelper.getPluginsIngredientUnderMouse(guiContainer, mouseX, mouseY),
			getSlotIngredientUnderMouse(guiContainer).stream()
		);
	}

	private Optional<IClickedIngredient<?>> getSlotIngredientUnderMouse(AbstractContainerScreen<?> guiContainer) {
		return Optional.ofNullable(guiContainer.getSlotUnderMouse())
			.flatMap(this::getClickedIngredient);
	}

	private Optional<IClickedIngredient<?>> getClickedIngredient(Slot slot) {
		ItemStack stack = slot.getItem();
		return TypedIngredient.createTyped(this.registeredIngredients, VanillaTypes.ITEM, stack)
			.map(typedIngredient -> {
				ImmutableRect2i slotArea = new ImmutableRect2i(slot.x, slot.y, 16, 16);
				return new ClickedIngredient<>(typedIngredient, slotArea, false, false);
			});
	}
}

@@ -1545,14 +1545,16 @@
 Map(
-this::
+slot -%3E 
 getC
@@ -1569,16 +1569,36 @@
 gredient
+(slot, guiContainer)
 );%0A%09%7D%0A%0A%09
@@ -1667,16 +1667,57 @@
 lot slot
+, AbstractContainerScreen%3C?%3E guiContainer
 ) %7B%0A%09%09It
@@ -1923,30 +1923,115 @@
 t2i(
-slot.x, slot.y, 16, 16
+%0A%09%09%09%09%09%09guiContainer.getGuiLeft() + slot.x,%0A%09%09%09%09%09%09guiContainer.getGuiTop() + slot.y,%0A%09%09%09%09%09%0916,%0A%09%09%09%09%09%0916%0A%09%09%09%09
 );%0A%09

Fix #2752 Crash on gui slots that are to the left or above the gui