package net.minecraft.world.inventory;

import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.entity.player.StackedContents;
import java.util.Optional;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;

public class CraftingMenu extends RecipeBookMenu<CraftingContainer> {
    private final CraftingContainer craftSlots;
    private final ResultContainer resultSlots;
    private final ContainerLevelAccess access;
    private final Player player;
    
    public CraftingMenu(final int integer, final Inventory beb) {
        this(integer, beb, ContainerLevelAccess.NULL);
    }
    
    public CraftingMenu(final int integer, final Inventory beb, final ContainerLevelAccess bgs) {
        super(MenuType.CRAFTING, integer);
        this.craftSlots = new CraftingContainer(this, 3, 3);
        this.resultSlots = new ResultContainer();
        this.access = bgs;
        this.player = beb.player;
        this.addSlot(new ResultSlot(beb.player, this.craftSlots, this.resultSlots, 0, 124, 35));
        for (int integer2 = 0; integer2 < 3; ++integer2) {
            for (int integer3 = 0; integer3 < 3; ++integer3) {
                this.addSlot(new Slot(this.craftSlots, integer3 + integer2 * 3, 30 + integer3 * 18, 17 + integer2 * 18));
            }
        }
        for (int integer2 = 0; integer2 < 3; ++integer2) {
            for (int integer3 = 0; integer3 < 9; ++integer3) {
                this.addSlot(new Slot(beb, integer3 + integer2 * 9 + 9, 8 + integer3 * 18, 84 + integer2 * 18));
            }
        }
        for (int integer2 = 0; integer2 < 9; ++integer2) {
            this.addSlot(new Slot(beb, integer2, 8 + integer2 * 18, 142));
        }
    }
    
    protected static void slotChangedCraftingGrid(final int integer, final Level bqb, final Player bec, final CraftingContainer bgu, final ResultContainer bhr) {
        if (bqb.isClientSide) {
            return;
        }
        final ServerPlayer ze6 = (ServerPlayer)bec;
        ItemStack bki7 = ItemStack.EMPTY;
        final Optional<CraftingRecipe> optional8 = bqb.getServer().getRecipeManager().<CraftingContainer, CraftingRecipe>getRecipeFor(RecipeType.CRAFTING, bgu, bqb);
        if (optional8.isPresent()) {
            final CraftingRecipe bmm9 = optional8.get();
            if (bhr.setRecipeUsed(bqb, ze6, bmm9)) {
                bki7 = bmm9.assemble(bgu);
            }
        }
        bhr.setItem(0, bki7);
        ze6.connection.send(new ClientboundContainerSetSlotPacket(integer, 0, bki7));
    }
    
    @Override
    public void slotsChanged(final Container amz) {
        this.access.execute((bqb, fu) -> slotChangedCraftingGrid(this.containerId, bqb, this.player, this.craftSlots, this.resultSlots));
    }
    
    @Override
    public void fillCraftSlotsStackedContents(final StackedContents bee) {
        this.craftSlots.fillStackedContents(bee);
    }
    
    @Override
    public void clearCraftingContent() {
        this.craftSlots.clearContent();
        this.resultSlots.clearContent();
    }
    
    @Override
    public boolean recipeMatches(final Recipe<? super CraftingContainer> bmu) {
        return bmu.matches(this.craftSlots, this.player.level);
    }
    
    @Override
    public void removed(final Player bec) {
        super.removed(bec);
        this.access.execute((bqb, fu) -> this.clearContainer(bec, bqb, this.craftSlots));
    }
    
    @Override
    public boolean stillValid(final Player bec) {
        return AbstractContainerMenu.stillValid(this.access, bec, Blocks.CRAFTING_TABLE);
    }
    
    @Override
    public ItemStack quickMoveStack(final Player bec, final int integer) {
        ItemStack bki4 = ItemStack.EMPTY;
        final Slot bhw5 = this.slots.get(integer);
        if (bhw5 != null && bhw5.hasItem()) {
            final ItemStack bki5 = bhw5.getItem();
            bki4 = bki5.copy();
            if (integer == 0) {
                final ItemStack bki7;
                this.access.execute((bqb, fu) -> bki7.getItem().onCraftedBy(bki7, bqb, bec));
                if (!this.moveItemStackTo(bki5, 10, 46, true)) {
                    return ItemStack.EMPTY;
                }
                bhw5.onQuickCraft(bki5, bki4);
            }
            else if (integer >= 10 && integer < 46) {
                if (!this.moveItemStackTo(bki5, 1, 10, false)) {
                    if (integer < 37) {
                        if (!this.moveItemStackTo(bki5, 37, 46, false)) {
                            return ItemStack.EMPTY;
                        }
                    }
                    else if (!this.moveItemStackTo(bki5, 10, 37, false)) {
                        return ItemStack.EMPTY;
                    }
                }
            }
            else if (!this.moveItemStackTo(bki5, 10, 46, false)) {
                return ItemStack.EMPTY;
            }
            if (bki5.isEmpty()) {
                bhw5.set(ItemStack.EMPTY);
            }
            else {
                bhw5.setChanged();
            }
            if (bki5.getCount() == bki4.getCount()) {
                return ItemStack.EMPTY;
            }
            final ItemStack bki6 = bhw5.onTake(bec, bki5);
            if (integer == 0) {
                bec.drop(bki6, false);
            }
        }
        return bki4;
    }
    
    @Override
    public boolean canTakeItemForPickAll(final ItemStack bki, final Slot bhw) {
        return bhw.container != this.resultSlots && super.canTakeItemForPickAll(bki, bhw);
    }
    
    @Override
    public int getResultSlotIndex() {
        return 0;
    }
    
    @Override
    public int getGridWidth() {
        return this.craftSlots.getWidth();
    }
    
    @Override
    public int getGridHeight() {
        return this.craftSlots.getHeight();
    }
    
    @Override
    public int getSize() {
        return 10;
    }
}
