package net.minecraft.world.inventory;

import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.Container;
import net.minecraft.world.entity.npc.ClientSideMerchant;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.trading.Merchant;

public class MerchantMenu extends AbstractContainerMenu {
    private final Merchant trader;
    private final MerchantContainer tradeContainer;
    private int merchantLevel;
    private boolean showProgressBar;
    private boolean canRestock;
    
    public MerchantMenu(final int integer, final Inventory beb) {
        this(integer, beb, new ClientSideMerchant(beb.player));
    }
    
    public MerchantMenu(final int integer, final Inventory beb, final Merchant boy) {
        super(MenuType.MERCHANT, integer);
        this.trader = boy;
        this.tradeContainer = new MerchantContainer(boy);
        this.addSlot(new Slot(this.tradeContainer, 0, 136, 37));
        this.addSlot(new Slot(this.tradeContainer, 1, 162, 37));
        this.addSlot(new MerchantResultSlot(beb.player, boy, this.tradeContainer, 2, 220, 37));
        for (int integer2 = 0; integer2 < 3; ++integer2) {
            for (int integer3 = 0; integer3 < 9; ++integer3) {
                this.addSlot(new Slot(beb, integer3 + integer2 * 9 + 9, 108 + integer3 * 18, 84 + integer2 * 18));
            }
        }
        for (int integer2 = 0; integer2 < 9; ++integer2) {
            this.addSlot(new Slot(beb, integer2, 108 + integer2 * 18, 142));
        }
    }
    
    public void setShowProgressBar(final boolean boolean1) {
        this.showProgressBar = boolean1;
    }
    
    @Override
    public void slotsChanged(final Container amz) {
        this.tradeContainer.updateSellItem();
        super.slotsChanged(amz);
    }
    
    public void setSelectionHint(final int integer) {
        this.tradeContainer.setSelectionHint(integer);
    }
    
    @Override
    public boolean stillValid(final Player bec) {
        return this.trader.getTradingPlayer() == bec;
    }
    
    public int getTraderXp() {
        return this.trader.getVillagerXp();
    }
    
    public int getFutureTraderXp() {
        return this.tradeContainer.getFutureXp();
    }
    
    public void setXp(final int integer) {
        this.trader.overrideXp(integer);
    }
    
    public int getTraderLevel() {
        return this.merchantLevel;
    }
    
    public void setMerchantLevel(final int integer) {
        this.merchantLevel = integer;
    }
    
    public void setCanRestock(final boolean boolean1) {
        this.canRestock = boolean1;
    }
    
    public boolean canRestock() {
        return this.canRestock;
    }
    
    @Override
    public boolean canTakeItemForPickAll(final ItemStack bki, final Slot bhw) {
        return false;
    }
    
    @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 == 2) {
                if (!this.moveItemStackTo(bki5, 3, 39, true)) {
                    return ItemStack.EMPTY;
                }
                bhw5.onQuickCraft(bki5, bki4);
                this.playTradeSound();
            }
            else if (integer == 0 || integer == 1) {
                if (!this.moveItemStackTo(bki5, 3, 39, 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;
    }
    
    private void playTradeSound() {
        if (!this.trader.getLevel().isClientSide) {
            final Entity aom2 = (Entity)this.trader;
            this.trader.getLevel().playLocalSound(aom2.getX(), aom2.getY(), aom2.getZ(), this.trader.getNotifyTradeSound(), SoundSource.NEUTRAL, 1.0f, 1.0f, false);
        }
    }
    
    @Override
    public void removed(final Player bec) {
        super.removed(bec);
        this.trader.setTradingPlayer(null);
        if (this.trader.getLevel().isClientSide) {
            return;
        }
        if (!bec.isAlive() || (bec instanceof ServerPlayer && ((ServerPlayer)bec).hasDisconnected())) {
            ItemStack bki3 = this.tradeContainer.removeItemNoUpdate(0);
            if (!bki3.isEmpty()) {
                bec.drop(bki3, false);
            }
            bki3 = this.tradeContainer.removeItemNoUpdate(1);
            if (!bki3.isEmpty()) {
                bec.drop(bki3, false);
            }
        }
        else {
            bec.inventory.placeItemBackInInventory(bec.level, this.tradeContainer.removeItemNoUpdate(0));
            bec.inventory.placeItemBackInInventory(bec.level, this.tradeContainer.removeItemNoUpdate(1));
        }
    }
    
    public void tryMoveItems(final int integer) {
        if (this.getOffers().size() <= integer) {
            return;
        }
        final ItemStack bki3 = this.tradeContainer.getItem(0);
        if (!bki3.isEmpty()) {
            if (!this.moveItemStackTo(bki3, 3, 39, true)) {
                return;
            }
            this.tradeContainer.setItem(0, bki3);
        }
        final ItemStack bki4 = this.tradeContainer.getItem(1);
        if (!bki4.isEmpty()) {
            if (!this.moveItemStackTo(bki4, 3, 39, true)) {
                return;
            }
            this.tradeContainer.setItem(1, bki4);
        }
        if (this.tradeContainer.getItem(0).isEmpty() && this.tradeContainer.getItem(1).isEmpty()) {
            final ItemStack bki5 = this.getOffers().get(integer).getCostA();
            this.moveFromInventoryToPaymentSlot(0, bki5);
            final ItemStack bki6 = this.getOffers().get(integer).getCostB();
            this.moveFromInventoryToPaymentSlot(1, bki6);
        }
    }
    
    private void moveFromInventoryToPaymentSlot(final int integer, final ItemStack bki) {
        if (!bki.isEmpty()) {
            for (int integer2 = 3; integer2 < 39; ++integer2) {
                final ItemStack bki2 = this.slots.get(integer2).getItem();
                if (!bki2.isEmpty() && this.isSameItem(bki, bki2)) {
                    final ItemStack bki3 = this.tradeContainer.getItem(integer);
                    final int integer3 = bki3.isEmpty() ? 0 : bki3.getCount();
                    final int integer4 = Math.min(bki.getMaxStackSize() - integer3, bki2.getCount());
                    final ItemStack bki4 = bki2.copy();
                    final int integer5 = integer3 + integer4;
                    bki2.shrink(integer4);
                    bki4.setCount(integer5);
                    this.tradeContainer.setItem(integer, bki4);
                    if (integer5 >= bki.getMaxStackSize()) {
                        break;
                    }
                }
            }
        }
    }
    
    private boolean isSameItem(final ItemStack bki1, final ItemStack bki2) {
        return bki1.getItem() == bki2.getItem() && ItemStack.tagMatches(bki1, bki2);
    }
    
    public void setOffers(final MerchantOffers bpa) {
        this.trader.overrideOffers(bpa);
    }
    
    public MerchantOffers getOffers() {
        return this.trader.getOffers();
    }
    
    public boolean showProgressBar() {
        return this.showProgressBar;
    }
}
