package net.minecraft.world.item.trading;

import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.util.Mth;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;

public class MerchantOffer {
    private final ItemStack baseCostA;
    private final ItemStack costB;
    private final ItemStack result;
    private int uses;
    private final int maxUses;
    private boolean rewardExp;
    private int specialPriceDiff;
    private int demand;
    private float priceMultiplier;
    private int xp;
    
    public MerchantOffer(final CompoundTag le) {
        this.rewardExp = true;
        this.xp = 1;
        this.baseCostA = ItemStack.of(le.getCompound("buy"));
        this.costB = ItemStack.of(le.getCompound("buyB"));
        this.result = ItemStack.of(le.getCompound("sell"));
        this.uses = le.getInt("uses");
        if (le.contains("maxUses", 99)) {
            this.maxUses = le.getInt("maxUses");
        }
        else {
            this.maxUses = 4;
        }
        if (le.contains("rewardExp", 1)) {
            this.rewardExp = le.getBoolean("rewardExp");
        }
        if (le.contains("xp", 3)) {
            this.xp = le.getInt("xp");
        }
        if (le.contains("priceMultiplier", 5)) {
            this.priceMultiplier = le.getFloat("priceMultiplier");
        }
        this.specialPriceDiff = le.getInt("specialPrice");
        this.demand = le.getInt("demand");
    }
    
    public MerchantOffer(final ItemStack bki1, final ItemStack bki2, final int integer3, final int integer4, final float float5) {
        this(bki1, ItemStack.EMPTY, bki2, integer3, integer4, float5);
    }
    
    public MerchantOffer(final ItemStack bki1, final ItemStack bki2, final ItemStack bki3, final int integer4, final int integer5, final float float6) {
        this(bki1, bki2, bki3, 0, integer4, integer5, float6);
    }
    
    public MerchantOffer(final ItemStack bki1, final ItemStack bki2, final ItemStack bki3, final int integer4, final int integer5, final int integer6, final float float7) {
        this(bki1, bki2, bki3, integer4, integer5, integer6, float7, 0);
    }
    
    public MerchantOffer(final ItemStack bki1, final ItemStack bki2, final ItemStack bki3, final int integer4, final int integer5, final int integer6, final float float7, final int integer8) {
        this.rewardExp = true;
        this.xp = 1;
        this.baseCostA = bki1;
        this.costB = bki2;
        this.result = bki3;
        this.uses = integer4;
        this.maxUses = integer5;
        this.xp = integer6;
        this.priceMultiplier = float7;
        this.demand = integer8;
    }
    
    public ItemStack getBaseCostA() {
        return this.baseCostA;
    }
    
    public ItemStack getCostA() {
        final int integer2 = this.baseCostA.getCount();
        final ItemStack bki3 = this.baseCostA.copy();
        final int integer3 = Math.max(0, Mth.floor(integer2 * this.demand * this.priceMultiplier));
        bki3.setCount(Mth.clamp(integer2 + integer3 + this.specialPriceDiff, 1, this.baseCostA.getItem().getMaxStackSize()));
        return bki3;
    }
    
    public ItemStack getCostB() {
        return this.costB;
    }
    
    public ItemStack getResult() {
        return this.result;
    }
    
    public void updateDemand() {
        this.demand = this.demand + this.uses - (this.maxUses - this.uses);
    }
    
    public ItemStack assemble() {
        return this.result.copy();
    }
    
    public int getUses() {
        return this.uses;
    }
    
    public void resetUses() {
        this.uses = 0;
    }
    
    public int getMaxUses() {
        return this.maxUses;
    }
    
    public void increaseUses() {
        ++this.uses;
    }
    
    public int getDemand() {
        return this.demand;
    }
    
    public void addToSpecialPriceDiff(final int integer) {
        this.specialPriceDiff += integer;
    }
    
    public void resetSpecialPriceDiff() {
        this.specialPriceDiff = 0;
    }
    
    public int getSpecialPriceDiff() {
        return this.specialPriceDiff;
    }
    
    public void setSpecialPriceDiff(final int integer) {
        this.specialPriceDiff = integer;
    }
    
    public float getPriceMultiplier() {
        return this.priceMultiplier;
    }
    
    public int getXp() {
        return this.xp;
    }
    
    public boolean isOutOfStock() {
        return this.uses >= this.maxUses;
    }
    
    public void setToOutOfStock() {
        this.uses = this.maxUses;
    }
    
    public boolean needsRestock() {
        return this.uses > 0;
    }
    
    public boolean shouldRewardExp() {
        return this.rewardExp;
    }
    
    public CompoundTag createTag() {
        final CompoundTag le2 = new CompoundTag();
        le2.put("buy", this.baseCostA.save(new CompoundTag()));
        le2.put("sell", this.result.save(new CompoundTag()));
        le2.put("buyB", this.costB.save(new CompoundTag()));
        le2.putInt("uses", this.uses);
        le2.putInt("maxUses", this.maxUses);
        le2.putBoolean("rewardExp", this.rewardExp);
        le2.putInt("xp", this.xp);
        le2.putFloat("priceMultiplier", this.priceMultiplier);
        le2.putInt("specialPrice", this.specialPriceDiff);
        le2.putInt("demand", this.demand);
        return le2;
    }
    
    public boolean satisfiedBy(final ItemStack bki1, final ItemStack bki2) {
        return this.isRequiredItem(bki1, this.getCostA()) && bki1.getCount() >= this.getCostA().getCount() && this.isRequiredItem(bki2, this.costB) && bki2.getCount() >= this.costB.getCount();
    }
    
    private boolean isRequiredItem(final ItemStack bki1, final ItemStack bki2) {
        if (bki2.isEmpty() && bki1.isEmpty()) {
            return true;
        }
        final ItemStack bki3 = bki1.copy();
        if (bki3.getItem().canBeDepleted()) {
            bki3.setDamageValue(bki3.getDamageValue());
        }
        return ItemStack.isSame(bki3, bki2) && (!bki2.hasTag() || (bki3.hasTag() && NbtUtils.compareNbt(bki2.getTag(), bki3.getTag(), false)));
    }
    
    public boolean take(final ItemStack bki1, final ItemStack bki2) {
        if (!this.satisfiedBy(bki1, bki2)) {
            return false;
        }
        bki1.shrink(this.getCostA().getCount());
        if (!this.getCostB().isEmpty()) {
            bki2.shrink(this.getCostB().getCount());
        }
        return true;
    }
}
