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 ayi) {
        this(integer, ayi, ContainerLevelAccess.NULL);
    }
    
    public StonecutterMenu(final int integer, final Inventory ayi, final ContainerLevelAccess bax) {
        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 = bax;
        this.level = ayi.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 ben) {
                return false;
            }
            
            @Override
            public ItemStack onTake(final Player ayj, final ItemStack ben) {
                final ItemStack ben2 = StonecutterMenu.this.inputSlot.remove(1);
                if (!ben2.isEmpty()) {
                    StonecutterMenu.this.setupResultSlot();
                }
                ben.getItem().onCraftedBy(ben, ayj.level, ayj);
                final long long4;
                bax.execute((bjw, fk) -> {
                    long4 = bjw.getGameTime();
                    if (StonecutterMenu.this.lastSoundTime != long4) {
                        bjw.playSound(null, fk, SoundEvents.UI_STONECUTTER_TAKE_RESULT, SoundSource.BLOCKS, 1.0f, 1.0f);
                        StonecutterMenu.this.lastSoundTime = long4;
                    }
                    return;
                });
                return super.onTake(ayj, ben);
            }
        });
        for (int integer2 = 0; integer2 < 3; ++integer2) {
            for (int integer3 = 0; integer3 < 9; ++integer3) {
                this.addSlot(new Slot(ayi, integer3 + integer2 * 9 + 9, 8 + integer3 * 18, 84 + integer2 * 18));
            }
        }
        for (int integer2 = 0; integer2 < 9; ++integer2) {
            this.addSlot(new Slot(ayi, 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 ayj) {
        return AbstractContainerMenu.stillValid(this.access, ayj, Blocks.STONECUTTER);
    }
    
    @Override
    public boolean clickMenuButton(final Player ayj, final int integer) {
        if (integer >= 0 && integer < this.recipes.size()) {
            this.selectedRecipeIndex.set(integer);
            this.setupResultSlot();
        }
        return true;
    }
    
    @Override
    public void slotsChanged(final Container aje) {
        final ItemStack ben3 = this.inputSlot.getItem();
        if (ben3.getItem() != this.input.getItem()) {
            this.input = ben3.copy();
            this.setupRecipeList(aje, ben3);
        }
    }
    
    private void setupRecipeList(final Container aje, final ItemStack ben) {
        this.recipes.clear();
        this.selectedRecipeIndex.set(-1);
        this.resultSlot.set(ItemStack.EMPTY);
        if (!ben.isEmpty()) {
            this.recipes = this.level.getRecipeManager().<Container, StonecutterRecipe>getRecipesFor(RecipeType.STONECUTTING, aje, this.level);
        }
    }
    
    private void setupResultSlot() {
        if (!this.recipes.isEmpty()) {
            final StonecutterRecipe bhk2 = this.recipes.get(this.selectedRecipeIndex.get());
            this.resultSlot.set(bhk2.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 ben, final Slot bca) {
        return bca.container != this.resultContainer && super.canTakeItemForPickAll(ben, bca);
    }
    
    @Override
    public ItemStack quickMoveStack(final Player ayj, final int integer) {
        ItemStack ben4 = ItemStack.EMPTY;
        final Slot bca5 = this.slots.get(integer);
        if (bca5 != null && bca5.hasItem()) {
            final ItemStack ben5 = bca5.getItem();
            final Item bei7 = ben5.getItem();
            ben4 = ben5.copy();
            if (integer == 1) {
                bei7.onCraftedBy(ben5, ayj.level, ayj);
                if (!this.moveItemStackTo(ben5, 2, 38, true)) {
                    return ItemStack.EMPTY;
                }
                bca5.onQuickCraft(ben5, ben4);
            }
            else if (integer == 0) {
                if (!this.moveItemStackTo(ben5, 2, 38, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (this.level.getRecipeManager().<SimpleContainer, StonecutterRecipe>getRecipeFor(RecipeType.STONECUTTING, new SimpleContainer(new ItemStack[] { ben5 }), this.level).isPresent()) {
                if (!this.moveItemStackTo(ben5, 0, 1, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 2 && integer < 29) {
                if (!this.moveItemStackTo(ben5, 29, 38, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 29 && integer < 38 && !this.moveItemStackTo(ben5, 2, 29, false)) {
                return ItemStack.EMPTY;
            }
            if (ben5.isEmpty()) {
                bca5.set(ItemStack.EMPTY);
            }
            bca5.setChanged();
            if (ben5.getCount() == ben4.getCount()) {
                return ItemStack.EMPTY;
            }
            bca5.onTake(ayj, ben5);
            this.broadcastChanges();
        }
        return ben4;
    }
    
    @Override
    public void removed(final Player ayj) {
        super.removed(ayj);
        this.resultContainer.removeItemNoUpdate(1);
        this.access.execute((bjw, fk) -> this.clearContainer(ayj, ayj.level, this.container));
    }
}
