package net.minecraft.world.inventory;

import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.world.item.EnchantedBookItem;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.entity.player.Player;
import java.util.List;
import net.minecraft.core.Registry;
import net.minecraft.world.item.enchantment.EnchantmentInstance;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import java.util.Random;
import net.minecraft.world.Container;

public class EnchantmentMenu extends AbstractContainerMenu {
    private final Container enchantSlots;
    private final ContainerLevelAccess access;
    private final Random random;
    private final DataSlot enchantmentSeed;
    public final int[] costs;
    public final int[] enchantClue;
    public final int[] levelClue;
    
    public EnchantmentMenu(final int integer, final Inventory ayi) {
        this(integer, ayi, ContainerLevelAccess.NULL);
    }
    
    public EnchantmentMenu(final int integer, final Inventory ayi, final ContainerLevelAccess bax) {
        super(MenuType.ENCHANTMENT, integer);
        this.enchantSlots = new SimpleContainer(2) {
            @Override
            public void setChanged() {
                super.setChanged();
                EnchantmentMenu.this.slotsChanged(this);
            }
        };
        this.random = new Random();
        this.enchantmentSeed = DataSlot.standalone();
        this.costs = new int[3];
        this.enchantClue = new int[] { -1, -1, -1 };
        this.levelClue = new int[] { -1, -1, -1 };
        this.access = bax;
        this.addSlot(new Slot(this.enchantSlots, 0, 15, 47) {
            @Override
            public boolean mayPlace(final ItemStack ben) {
                return true;
            }
            
            @Override
            public int getMaxStackSize() {
                return 1;
            }
        });
        this.addSlot(new Slot(this.enchantSlots, 1, 35, 47) {
            @Override
            public boolean mayPlace(final ItemStack ben) {
                return ben.getItem() == Items.LAPIS_LAZULI;
            }
        });
        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(DataSlot.shared(this.costs, 0));
        this.addDataSlot(DataSlot.shared(this.costs, 1));
        this.addDataSlot(DataSlot.shared(this.costs, 2));
        this.addDataSlot(this.enchantmentSeed).set(ayi.player.getEnchantmentSeed());
        this.addDataSlot(DataSlot.shared(this.enchantClue, 0));
        this.addDataSlot(DataSlot.shared(this.enchantClue, 1));
        this.addDataSlot(DataSlot.shared(this.enchantClue, 2));
        this.addDataSlot(DataSlot.shared(this.levelClue, 0));
        this.addDataSlot(DataSlot.shared(this.levelClue, 1));
        this.addDataSlot(DataSlot.shared(this.levelClue, 2));
    }
    
    @Override
    public void slotsChanged(final Container aje) {
        if (aje == this.enchantSlots) {
            final ItemStack ben3 = aje.getItem(0);
            if (ben3.isEmpty() || !ben3.isEnchantable()) {
                for (int integer4 = 0; integer4 < 3; ++integer4) {
                    this.costs[integer4] = 0;
                    this.enchantClue[integer4] = -1;
                    this.levelClue[integer4] = -1;
                }
            }
            else {
                int integer5;
                int integer6;
                int integer7;
                int integer8;
                final ItemStack itemStack;
                int integer9;
                List<EnchantmentInstance> list7;
                EnchantmentInstance bia8;
                this.access.execute((bjw, fk) -> {
                    integer5 = 0;
                    for (integer6 = -1; integer6 <= 1; ++integer6) {
                        for (integer7 = -1; integer7 <= 1; ++integer7) {
                            if (integer6 != 0 || integer7 != 0) {
                                if (bjw.isEmptyBlock(fk.offset(integer7, 0, integer6)) && bjw.isEmptyBlock(fk.offset(integer7, 1, integer6))) {
                                    if (bjw.getBlockState(fk.offset(integer7 * 2, 0, integer6 * 2)).getBlock() == Blocks.BOOKSHELF) {
                                        ++integer5;
                                    }
                                    if (bjw.getBlockState(fk.offset(integer7 * 2, 1, integer6 * 2)).getBlock() == Blocks.BOOKSHELF) {
                                        ++integer5;
                                    }
                                    if (integer7 != 0 && integer6 != 0) {
                                        if (bjw.getBlockState(fk.offset(integer7 * 2, 0, integer6)).getBlock() == Blocks.BOOKSHELF) {
                                            ++integer5;
                                        }
                                        if (bjw.getBlockState(fk.offset(integer7 * 2, 1, integer6)).getBlock() == Blocks.BOOKSHELF) {
                                            ++integer5;
                                        }
                                        if (bjw.getBlockState(fk.offset(integer7, 0, integer6 * 2)).getBlock() == Blocks.BOOKSHELF) {
                                            ++integer5;
                                        }
                                        if (bjw.getBlockState(fk.offset(integer7, 1, integer6 * 2)).getBlock() == Blocks.BOOKSHELF) {
                                            ++integer5;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    this.random.setSeed(this.enchantmentSeed.get());
                    for (integer8 = 0; integer8 < 3; ++integer8) {
                        this.costs[integer8] = EnchantmentHelper.getEnchantmentCost(this.random, integer8, integer5, itemStack);
                        this.enchantClue[integer8] = -1;
                        this.levelClue[integer8] = -1;
                        if (this.costs[integer8] < integer8 + 1) {
                            this.costs[integer8] = 0;
                        }
                    }
                    for (integer9 = 0; integer9 < 3; ++integer9) {
                        if (this.costs[integer9] > 0) {
                            list7 = this.getEnchantmentList(itemStack, integer9, this.costs[integer9]);
                            if (list7 != null && !list7.isEmpty()) {
                                bia8 = list7.get(this.random.nextInt(list7.size()));
                                this.enchantClue[integer9] = Registry.ENCHANTMENT.getId(bia8.enchantment);
                                this.levelClue[integer9] = bia8.level;
                            }
                        }
                    }
                    this.broadcastChanges();
                });
            }
        }
    }
    
    @Override
    public boolean clickMenuButton(final Player ayj, final int integer) {
        final ItemStack ben4 = this.enchantSlots.getItem(0);
        final ItemStack ben5 = this.enchantSlots.getItem(1);
        final int integer2 = integer + 1;
        if ((ben5.isEmpty() || ben5.getCount() < integer2) && !ayj.abilities.instabuild) {
            return false;
        }
        if (this.costs[integer] > 0 && !ben4.isEmpty() && ((ayj.experienceLevel >= integer2 && ayj.experienceLevel >= this.costs[integer]) || ayj.abilities.instabuild)) {
            final ItemStack itemStack;
            ItemStack ben6;
            final List<EnchantmentInstance> list10;
            final int integer6;
            boolean boolean11;
            int integer5;
            EnchantmentInstance bia13;
            final ItemStack itemStack2;
            this.access.execute((bjw, fk) -> {
                ben6 = itemStack;
                list10 = this.getEnchantmentList(ben6, integer, this.costs[integer]);
                if (!list10.isEmpty()) {
                    ayj.onEnchantmentPerformed(ben6, integer6);
                    boolean11 = (ben6.getItem() == Items.BOOK);
                    if (boolean11) {
                        ben6 = new ItemStack(Items.ENCHANTED_BOOK);
                        this.enchantSlots.setItem(0, ben6);
                    }
                    for (integer5 = 0; integer5 < list10.size(); ++integer5) {
                        bia13 = list10.get(integer5);
                        if (boolean11) {
                            EnchantedBookItem.addEnchantment(ben6, bia13);
                        }
                        else {
                            ben6.enchant(bia13.enchantment, bia13.level);
                        }
                    }
                    if (!ayj.abilities.instabuild) {
                        itemStack2.shrink(integer6);
                        if (itemStack2.isEmpty()) {
                            this.enchantSlots.setItem(1, ItemStack.EMPTY);
                        }
                    }
                    ayj.awardStat(Stats.ENCHANT_ITEM);
                    if (ayj instanceof ServerPlayer) {
                        CriteriaTriggers.ENCHANTED_ITEM.trigger((ServerPlayer)ayj, ben6, integer6);
                    }
                    this.enchantSlots.setChanged();
                    this.enchantmentSeed.set(ayj.getEnchantmentSeed());
                    this.slotsChanged(this.enchantSlots);
                    bjw.playSound(null, fk, SoundEvents.ENCHANTMENT_TABLE_USE, SoundSource.BLOCKS, 1.0f, bjw.random.nextFloat() * 0.1f + 0.9f);
                }
                return;
            });
            return true;
        }
        return false;
    }
    
    private List<EnchantmentInstance> getEnchantmentList(final ItemStack ben, final int integer2, final int integer3) {
        this.random.setSeed(this.enchantmentSeed.get() + integer2);
        final List<EnchantmentInstance> list5 = EnchantmentHelper.selectEnchantment(this.random, ben, integer3, false);
        if (ben.getItem() == Items.BOOK && list5.size() > 1) {
            list5.remove(this.random.nextInt(list5.size()));
        }
        return list5;
    }
    
    public int getGoldCount() {
        final ItemStack ben2 = this.enchantSlots.getItem(1);
        if (ben2.isEmpty()) {
            return 0;
        }
        return ben2.getCount();
    }
    
    public int getEnchantmentSeed() {
        return this.enchantmentSeed.get();
    }
    
    @Override
    public void removed(final Player ayj) {
        super.removed(ayj);
        this.access.execute((bjw, fk) -> this.clearContainer(ayj, ayj.level, this.enchantSlots));
    }
    
    @Override
    public boolean stillValid(final Player ayj) {
        return AbstractContainerMenu.stillValid(this.access, ayj, Blocks.ENCHANTING_TABLE);
    }
    
    @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();
            ben4 = ben5.copy();
            if (integer == 0) {
                if (!this.moveItemStackTo(ben5, 2, 38, true)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer == 1) {
                if (!this.moveItemStackTo(ben5, 2, 38, true)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (ben5.getItem() == Items.LAPIS_LAZULI) {
                if (!this.moveItemStackTo(ben5, 1, 2, true)) {
                    return ItemStack.EMPTY;
                }
            }
            else {
                if (this.slots.get(0).hasItem() || !this.slots.get(0).mayPlace(ben5)) {
                    return ItemStack.EMPTY;
                }
                if (ben5.hasTag() && ben5.getCount() == 1) {
                    this.slots.get(0).set(ben5.copy());
                    ben5.setCount(0);
                }
                else if (!ben5.isEmpty()) {
                    this.slots.get(0).set(new ItemStack(ben5.getItem()));
                    ben5.shrink(1);
                }
            }
            if (ben5.isEmpty()) {
                bca5.set(ItemStack.EMPTY);
            }
            else {
                bca5.setChanged();
            }
            if (ben5.getCount() == ben4.getCount()) {
                return ItemStack.EMPTY;
            }
            bca5.onTake(ayj, ben5);
        }
        return ben4;
    }
}
