package net.minecraft.world.inventory;

import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.ItemLike;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.minecraft.world.item.Item;
import net.minecraft.core.BlockPos;
import java.util.Iterator;
import net.minecraft.world.item.enchantment.Enchantment;
import java.util.Map;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.world.entity.player.Player;
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 net.minecraft.world.Container;

public class GrindstoneMenu extends AbstractContainerMenu {
    private final Container resultSlots;
    private final Container repairSlots;
    private final ContainerLevelAccess access;
    
    public GrindstoneMenu(final int integer, final Inventory beb) {
        this(integer, beb, ContainerLevelAccess.NULL);
    }
    
    public GrindstoneMenu(final int integer, final Inventory beb, final ContainerLevelAccess bgs) {
        super(MenuType.GRINDSTONE, integer);
        this.resultSlots = new ResultContainer();
        this.repairSlots = new SimpleContainer(2) {
            @Override
            public void setChanged() {
                super.setChanged();
                GrindstoneMenu.this.slotsChanged(this);
            }
        };
        this.access = bgs;
        this.addSlot(new Slot(this.repairSlots, 0, 49, 19) {
            @Override
            public boolean mayPlace(final ItemStack bki) {
                return bki.isDamageableItem() || bki.getItem() == Items.ENCHANTED_BOOK || bki.isEnchanted();
            }
        });
        this.addSlot(new Slot(this.repairSlots, 1, 49, 40) {
            @Override
            public boolean mayPlace(final ItemStack bki) {
                return bki.isDamageableItem() || bki.getItem() == Items.ENCHANTED_BOOK || bki.isEnchanted();
            }
        });
        this.addSlot(new Slot(this.resultSlots, 2, 129, 34) {
            @Override
            public boolean mayPlace(final ItemStack bki) {
                return false;
            }
            
            @Override
            public ItemStack onTake(final Player bec, final ItemStack bki) {
                int integer4;
                int integer5;
                bgs.execute((bqb, fu) -> {
                    integer4 = this.getExperienceAmount(bqb);
                    while (integer4 > 0) {
                        integer5 = ExperienceOrb.getExperienceValue(integer4);
                        integer4 -= integer5;
                        bqb.addFreshEntity(new ExperienceOrb(bqb, fu.getX(), fu.getY() + 0.5, fu.getZ() + 0.5, integer5));
                    }
                    bqb.levelEvent(1042, fu, 0);
                    return;
                });
                GrindstoneMenu.this.repairSlots.setItem(0, ItemStack.EMPTY);
                GrindstoneMenu.this.repairSlots.setItem(1, ItemStack.EMPTY);
                return bki;
            }
            
            private int getExperienceAmount(final Level bqb) {
                int integer3 = 0;
                integer3 += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0));
                integer3 += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1));
                if (integer3 > 0) {
                    final int integer4 = (int)Math.ceil(integer3 / 2.0);
                    return integer4 + bqb.random.nextInt(integer4);
                }
                return 0;
            }
            
            private int getExperienceFromItem(final ItemStack bki) {
                int integer3 = 0;
                final Map<Enchantment, Integer> map4 = EnchantmentHelper.getEnchantments(bki);
                for (final Map.Entry<Enchantment, Integer> entry6 : map4.entrySet()) {
                    final Enchantment bnw7 = entry6.getKey();
                    final Integer integer4 = entry6.getValue();
                    if (!bnw7.isCurse()) {
                        integer3 += bnw7.getMinCost(integer4);
                    }
                }
                return integer3;
            }
        });
        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));
        }
    }
    
    @Override
    public void slotsChanged(final Container amz) {
        super.slotsChanged(amz);
        if (amz == this.repairSlots) {
            this.createResult();
        }
    }
    
    private void createResult() {
        final ItemStack bki2 = this.repairSlots.getItem(0);
        final ItemStack bki3 = this.repairSlots.getItem(1);
        final boolean boolean4 = !bki2.isEmpty() || !bki3.isEmpty();
        final boolean boolean5 = !bki2.isEmpty() && !bki3.isEmpty();
        if (boolean4) {
            final boolean boolean6 = (!bki2.isEmpty() && bki2.getItem() != Items.ENCHANTED_BOOK && !bki2.isEnchanted()) || (!bki3.isEmpty() && bki3.getItem() != Items.ENCHANTED_BOOK && !bki3.isEnchanted());
            if (bki2.getCount() > 1 || bki3.getCount() > 1 || (!boolean5 && boolean6)) {
                this.resultSlots.setItem(0, ItemStack.EMPTY);
                this.broadcastChanges();
                return;
            }
            int integer8 = 1;
            int integer12;
            ItemStack bki4;
            if (boolean5) {
                if (bki2.getItem() != bki3.getItem()) {
                    this.resultSlots.setItem(0, ItemStack.EMPTY);
                    this.broadcastChanges();
                    return;
                }
                final Item bke10 = bki2.getItem();
                final int integer9 = bke10.getMaxDamage() - bki2.getDamageValue();
                final int integer10 = bke10.getMaxDamage() - bki3.getDamageValue();
                final int integer11 = integer9 + integer10 + bke10.getMaxDamage() * 5 / 100;
                integer12 = Math.max(bke10.getMaxDamage() - integer11, 0);
                bki4 = this.mergeEnchants(bki2, bki3);
                if (!bki4.isDamageableItem()) {
                    if (!ItemStack.matches(bki2, bki3)) {
                        this.resultSlots.setItem(0, ItemStack.EMPTY);
                        this.broadcastChanges();
                        return;
                    }
                    integer8 = 2;
                }
            }
            else {
                final boolean boolean7 = !bki2.isEmpty();
                integer12 = (boolean7 ? bki2.getDamageValue() : bki3.getDamageValue());
                bki4 = (boolean7 ? bki2 : bki3);
            }
            this.resultSlots.setItem(0, this.removeNonCurses(bki4, integer12, integer8));
        }
        else {
            this.resultSlots.setItem(0, ItemStack.EMPTY);
        }
        this.broadcastChanges();
    }
    
    private ItemStack mergeEnchants(final ItemStack bki1, final ItemStack bki2) {
        final ItemStack bki3 = bki1.copy();
        final Map<Enchantment, Integer> map5 = EnchantmentHelper.getEnchantments(bki2);
        for (final Map.Entry<Enchantment, Integer> entry7 : map5.entrySet()) {
            final Enchantment bnw8 = entry7.getKey();
            if (!bnw8.isCurse() || EnchantmentHelper.getItemEnchantmentLevel(bnw8, bki3) == 0) {
                bki3.enchant(bnw8, entry7.getValue());
            }
        }
        return bki3;
    }
    
    private ItemStack removeNonCurses(final ItemStack bki, final int integer2, final int integer3) {
        ItemStack bki2 = bki.copy();
        bki2.removeTagKey("Enchantments");
        bki2.removeTagKey("StoredEnchantments");
        if (integer2 > 0) {
            bki2.setDamageValue(integer2);
        }
        else {
            bki2.removeTagKey("Damage");
        }
        bki2.setCount(integer3);
        final Map<Enchantment, Integer> map6 = EnchantmentHelper.getEnchantments(bki).entrySet().stream().filter(entry -> entry.getKey().isCurse()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        EnchantmentHelper.setEnchantments(map6, bki2);
        bki2.setRepairCost(0);
        if (bki2.getItem() == Items.ENCHANTED_BOOK && map6.size() == 0) {
            bki2 = new ItemStack(Items.BOOK);
            if (bki.hasCustomHoverName()) {
                bki2.setHoverName(bki.getHoverName());
            }
        }
        for (int integer4 = 0; integer4 < map6.size(); ++integer4) {
            bki2.setRepairCost(AnvilMenu.calculateIncreasedRepairCost(bki2.getBaseRepairCost()));
        }
        return bki2;
    }
    
    @Override
    public void removed(final Player bec) {
        super.removed(bec);
        this.access.execute((bqb, fu) -> this.clearContainer(bec, bqb, this.repairSlots));
    }
    
    @Override
    public boolean stillValid(final Player bec) {
        return AbstractContainerMenu.stillValid(this.access, bec, Blocks.GRINDSTONE);
    }
    
    @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();
            final ItemStack bki6 = this.repairSlots.getItem(0);
            final ItemStack bki7 = this.repairSlots.getItem(1);
            if (integer == 2) {
                if (!this.moveItemStackTo(bki5, 3, 39, true)) {
                    return ItemStack.EMPTY;
                }
                bhw5.onQuickCraft(bki5, bki4);
            }
            else if (integer == 0 || integer == 1) {
                if (!this.moveItemStackTo(bki5, 3, 39, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (bki6.isEmpty() || bki7.isEmpty()) {
                if (!this.moveItemStackTo(bki5, 0, 2, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 3 && integer < 30) {
                if (!this.moveItemStackTo(bki5, 30, 39, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 30 && integer < 39 && !this.moveItemStackTo(bki5, 3, 30, false)) {
                return ItemStack.EMPTY;
            }
            if (bki5.isEmpty()) {
                bhw5.set(ItemStack.EMPTY);
            }
            else {
                bhw5.setChanged();
            }
            if (bki5.getCount() == bki4.getCount()) {
                return ItemStack.EMPTY;
            }
            bhw5.onTake(bec, bki5);
        }
        return bki4;
    }
}
