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 ayi) {
        this(integer, ayi, new ClientSideMerchant(ayi.player));
    }
    
    public MerchantMenu(final int integer, final Inventory ayi, final Merchant biy) {
        super(MenuType.MERCHANT, integer);
        this.trader = biy;
        this.tradeContainer = new MerchantContainer(biy);
        this.addSlot(new Slot(this.tradeContainer, 0, 136, 37));
        this.addSlot(new Slot(this.tradeContainer, 1, 162, 37));
        this.addSlot(new MerchantResultSlot(ayi.player, biy, this.tradeContainer, 2, 220, 37));
        for (int integer2 = 0; integer2 < 3; ++integer2) {
            for (int integer3 = 0; integer3 < 9; ++integer3) {
                this.addSlot(new Slot(ayi, integer3 + integer2 * 9 + 9, 108 + integer3 * 18, 84 + integer2 * 18));
            }
        }
        for (int integer2 = 0; integer2 < 9; ++integer2) {
            this.addSlot(new Slot(ayi, integer2, 108 + integer2 * 18, 142));
        }
    }
    
    public void setShowProgressBar(final boolean boolean1) {
        this.showProgressBar = boolean1;
    }
    
    @Override
    public void slotsChanged(final Container aje) {
        this.tradeContainer.updateSellItem();
        super.slotsChanged(aje);
    }
    
    public void setSelectionHint(final int integer) {
        this.tradeContainer.setSelectionHint(integer);
    }
    
    @Override
    public boolean stillValid(final Player ayj) {
        return this.trader.getTradingPlayer() == ayj;
    }
    
    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 ben, final Slot bca) {
        return false;
    }
    
    @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 == 2) {
                if (!this.moveItemStackTo(ben5, 3, 39, true)) {
                    return ItemStack.EMPTY;
                }
                bca5.onQuickCraft(ben5, ben4);
                this.playTradeSound();
            }
            else if (integer == 0 || integer == 1) {
                if (!this.moveItemStackTo(ben5, 3, 39, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 3 && integer < 30) {
                if (!this.moveItemStackTo(ben5, 30, 39, false)) {
                    return ItemStack.EMPTY;
                }
            }
            else if (integer >= 30 && integer < 39 && !this.moveItemStackTo(ben5, 3, 30, false)) {
                return ItemStack.EMPTY;
            }
            if (ben5.isEmpty()) {
                bca5.set(ItemStack.EMPTY);
            }
            else {
                bca5.setChanged();
            }
            if (ben5.getCount() == ben4.getCount()) {
                return ItemStack.EMPTY;
            }
            bca5.onTake(ayj, ben5);
        }
        return ben4;
    }
    
    private void playTradeSound() {
        if (!this.trader.getLevel().isClientSide) {
            final Entity akq2 = (Entity)this.trader;
            this.trader.getLevel().playLocalSound(akq2.getX(), akq2.getY(), akq2.getZ(), this.trader.getNotifyTradeSound(), SoundSource.NEUTRAL, 1.0f, 1.0f, false);
        }
    }
    
    @Override
    public void removed(final Player ayj) {
        super.removed(ayj);
        this.trader.setTradingPlayer(null);
        if (this.trader.getLevel().isClientSide) {
            return;
        }
        if (!ayj.isAlive() || (ayj instanceof ServerPlayer && ((ServerPlayer)ayj).hasDisconnected())) {
            ItemStack ben3 = this.tradeContainer.removeItemNoUpdate(0);
            if (!ben3.isEmpty()) {
                ayj.drop(ben3, false);
            }
            ben3 = this.tradeContainer.removeItemNoUpdate(1);
            if (!ben3.isEmpty()) {
                ayj.drop(ben3, false);
            }
        }
        else {
            ayj.inventory.placeItemBackInInventory(ayj.level, this.tradeContainer.removeItemNoUpdate(0));
            ayj.inventory.placeItemBackInInventory(ayj.level, this.tradeContainer.removeItemNoUpdate(1));
        }
    }
    
    public void tryMoveItems(final int integer) {
        if (this.getOffers().size() <= integer) {
            return;
        }
        final ItemStack ben3 = this.tradeContainer.getItem(0);
        if (!ben3.isEmpty()) {
            if (!this.moveItemStackTo(ben3, 3, 39, true)) {
                return;
            }
            this.tradeContainer.setItem(0, ben3);
        }
        final ItemStack ben4 = this.tradeContainer.getItem(1);
        if (!ben4.isEmpty()) {
            if (!this.moveItemStackTo(ben4, 3, 39, true)) {
                return;
            }
            this.tradeContainer.setItem(1, ben4);
        }
        if (this.tradeContainer.getItem(0).isEmpty() && this.tradeContainer.getItem(1).isEmpty()) {
            final ItemStack ben5 = this.getOffers().get(integer).getCostA();
            this.moveFromInventoryToPaymentSlot(0, ben5);
            final ItemStack ben6 = this.getOffers().get(integer).getCostB();
            this.moveFromInventoryToPaymentSlot(1, ben6);
        }
    }
    
    private void moveFromInventoryToPaymentSlot(final int integer, final ItemStack ben) {
        if (!ben.isEmpty()) {
            for (int integer2 = 3; integer2 < 39; ++integer2) {
                final ItemStack ben2 = this.slots.get(integer2).getItem();
                if (!ben2.isEmpty() && this.isSameItem(ben, ben2)) {
                    final ItemStack ben3 = this.tradeContainer.getItem(integer);
                    final int integer3 = ben3.isEmpty() ? 0 : ben3.getCount();
                    final int integer4 = Math.min(ben.getMaxStackSize() - integer3, ben2.getCount());
                    final ItemStack ben4 = ben2.copy();
                    final int integer5 = integer3 + integer4;
                    ben2.shrink(integer4);
                    ben4.setCount(integer5);
                    this.tradeContainer.setItem(integer, ben4);
                    if (integer5 >= ben.getMaxStackSize()) {
                        break;
                    }
                }
            }
        }
    }
    
    private boolean isSameItem(final ItemStack ben1, final ItemStack ben2) {
        return ben1.getItem() == ben2.getItem() && ItemStack.tagMatches(ben1, ben2);
    }
    
    public void setOffers(final MerchantOffers bja) {
        this.trader.overrideOffers(bja);
    }
    
    public MerchantOffers getOffers() {
        return this.trader.getOffers();
    }
    
    public boolean showProgressBar() {
        return this.showProgressBar;
    }
}
