package net.minecraft.world.inventory;

import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.SimpleContainer;
import com.google.common.collect.Lists;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.StonecutterRecipe;
import java.util.List;
import net.minecraft.world.level.Level;

public class StonecutterMenu extends AbstractContainerMenu {
    private final ContainerLevelAccess access;
    private final DataSlot selectedRecipeIndex;
    private final Level level;
    private List<StonecutterRecipe> recipes;
    private ItemStack input;
    private long lastSoundTime;
    final Slot inputSlot;
    final Slot resultSlot;
    private Runnable slotUpdateListener;
    public final Container container;
    private final ResultContainer resultContainer;
    
    public StonecutterMenu(final int integer, final Inventory beb) {
        this(integer, beb, ContainerLevelAccess.NULL);
    }
    
    public StonecutterMenu(final int integer, final Inventory beb, final ContainerLevelAccess bgs) {
        super(MenuType.STONECUTTER, integer);
        this.selectedRecipeIndex = DataSlot.standalone();
        this.recipes = Lists.newArrayList();
        this.input = ItemStack.EMPTY;
        this.slotUpdateListener = (() -> {});
        this.container = new SimpleContainer(1) {
            @Override
            public void setChanged() {
                super.setChanged();
                StonecutterMenu.this.slotsChanged(this);
                StonecutterMenu.this.slotUpdateListener.run();
            }
        };
        this.resultContainer = new ResultContainer();
        this.access = bgs;
        this.level = beb.player.level;
        this.inputSlot = this.addSlot(new Slot(this.container, 0, 20, 33));
        this.resultSlot = this.addSlot(new Slot(this.resultContainer, 1, 143, 33) {
            @Override
            public boolean mayPlace(final ItemStack bki) {
                return false;
            }
            
            @Override
            public ItemStack onTake(final Player bec, final ItemStack bki) {
                final ItemStack bki2 = StonecutterMenu.this.inputSlot.remove(1);
                if (!bki2.isEmpty()) {
                    StonecutterMenu.this.setupResultSlot();
                }
                bki.getItem().onCraftedBy(bki, bec.level, bec);
                final long long4;
                bgs.execute((bqb, fu) -> {
                    long4 = bqb.getGameTime();
                    if (StonecutterMenu.this.lastSoundTime != long4) {
                        bqb.playSound(null, fu, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundSource.BLOCKS, 1.0f, 1.0f);
                        StonecutterMenu.this.lastSoundTime = long4;
                    }
                    return;
                });
                return super.onTake(bec, bki);
            }
        });
        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));
        }
        this.addDataSlot(this.selectedRecipeIndex);
    }
    
    public int getSelectedRecipeIndex() {
        return this.selectedRecipeIndex.get();
    }
    
    public List<StonecutterRecipe> getRecipes() {
        return this.recipes;
    }
    
    public int getNumRecipes() {
        return this.recipes.size();
    }
    
    public boolean hasInputItem() {
        return this.inputSlot.hasItem() && !this.recipes.isEmpty();
    }
    
    @Override
    public boolean stillValid(final Player bec) {
        return AbstractContainerMenu.stillValid(this.access, bec, Blocks.STONECUTTER);
    }
    
    @Override
    public boolean clickMenuButton(final Player bec, final int integer) {
        if (this.isValidRecipeIndex(integer)) {
            this.selectedRecipeIndex.set(integer);
            this.setupResultSlot();
        }
        return true;
    }
    
    private boolean isValidRecipeIndex(final int integer) {
        return integer >= 0 && integer < this.recipes.size();
    }
    
    @Override
    public void slotsChanged(final Container amz) {
        final ItemStack bki3 = this.inputSlot.getItem();
        if (bki3.getItem() != this.input.getItem()) {
            this.input = bki3.copy();
            this.setupRecipeList(amz, bki3);
        }
    }
    
    private void setupRecipeList(final Container amz, final ItemStack bki) {
        this.recipes.clear();
        this.selectedRecipeIndex.set(-1);
        this.resultSlot.set(ItemStack.EMPTY);
        if (!bki.isEmpty()) {
            this.recipes = this.level.getRecipeManager().<Container, StonecutterRecipe>getRecipesFor(RecipeType.STONECUTTING, amz, this.level);
        }
    }
    
    private void setupResultSlot() {
        if (!this.recipes.isEmpty() && this.isValidRecipeIndex(this.selectedRecipeIndex.get())) {
            final StonecutterRecipe bni2 = this.recipes.get(this.selectedRecipeIndex.get());
            this.resultSlot.set(bni2.assemble(this.container));
        }
        else {
            this.resultSlot.set(ItemStack.EMPTY);
        }
        this.broadcastChanges();
    }
    
    @Override
    public MenuType<?> getType() {
        return MenuType.STONECUTTER;
    }
    
    public void registerUpdateListener(final Runnable runnable) {
        this.slotUpdateListener = runnable;
    }
    
    @Override
    public boolean canTakeItemForPickAll(final ItemStack bki, final Slot bhw) {
        return bhw.container != this.resultContainer && super.canTakeItemForPickAll(bki, bhw);
    }
    
    @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();
            final Item bke7 = bki5.getItem();
            bki4 = bki5.copy();
            if (integer == 1) {
                bke7.onCraftedBy(bki5, bec.level, bec);
                if (!this.moveItemStackTo(bki5, 2, 38, true)) {
                    return ItemStack.EMPTY;
                }
                bhw5.onQuickCraft(bki5, bki4);
            }
            else if (integer == 0) {
                if (!this.moveItemStackTo(bki5, 2, 38, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (this.level.getRecipeManager().<SimpleContainer, StonecutterRecipe>getRecipeFor(RecipeType.STONECUTTING, new SimpleContainer(new ItemStack[] { bki5 }), this.level).isPresent()) {
                if (!this.moveItemStackTo(bki5, 0, 1, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 2 && integer < 29) {
                if (!this.moveItemStackTo(bki5, 29, 38, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 29 && integer < 38 && !this.moveItemStackTo(bki5, 2, 29, false)) {
                return ItemStack.EMPTY;
            }
            if (bki5.isEmpty()) {
                bhw5.set(ItemStack.EMPTY);
            }
            bhw5.setChanged();
            if (bki5.getCount() == bki4.getCount()) {
                return ItemStack.EMPTY;
            }
            bhw5.onTake(bec, bki5);
            this.broadcastChanges();
        }
        return bki4;
    }
    
    @Override
    public void removed(final Player bec) {
        super.removed(bec);
        this.resultContainer.removeItemNoUpdate(1);
        this.access.execute((bqb, fu) -> this.clearContainer(bec, bec.level, this.container));
    }
}
