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 jt) {
        this.rewardExp = true;
        this.xp = 1;
        this.baseCostA = ItemStack.of(jt.getCompound("buy"));
        this.costB = ItemStack.of(jt.getCompound("buyB"));
        this.result = ItemStack.of(jt.getCompound("sell"));
        this.uses = jt.getInt("uses");
        if (jt.contains("maxUses", 99)) {
            this.maxUses = jt.getInt("maxUses");
        }
        else {
            this.maxUses = 4;
        }
        if (jt.contains("rewardExp", 1)) {
            this.rewardExp = jt.getBoolean("rewardExp");
        }
        if (jt.contains("xp", 3)) {
            this.xp = jt.getInt("xp");
        }
        if (jt.contains("priceMultiplier", 5)) {
            this.priceMultiplier = jt.getFloat("priceMultiplier");
        }
        this.specialPriceDiff = jt.getInt("specialPrice");
        this.demand = jt.getInt("demand");
    }
    
    public MerchantOffer(final ItemStack ben1, final ItemStack ben2, final int integer3, final int integer4, final float float5) {
        this(ben1, ItemStack.EMPTY, ben2, integer3, integer4, float5);
    }
    
    public MerchantOffer(final ItemStack ben1, final ItemStack ben2, final ItemStack ben3, final int integer4, final int integer5, final float float6) {
        this(ben1, ben2, ben3, 0, integer4, integer5, float6);
    }
    
    public MerchantOffer(final ItemStack ben1, final ItemStack ben2, final ItemStack ben3, final int integer4, final int integer5, final int integer6, final float float7) {
        this(ben1, ben2, ben3, integer4, integer5, integer6, float7, 0);
    }
    
    public MerchantOffer(final ItemStack ben1, final ItemStack ben2, final ItemStack ben3, final int integer4, final int integer5, final int integer6, final float float7, final int integer8) {
        this.rewardExp = true;
        this.xp = 1;
        this.baseCostA = ben1;
        this.costB = ben2;
        this.result = ben3;
        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 ben3 = this.baseCostA.copy();
        final int integer3 = Math.max(0, Mth.floor(integer2 * this.demand * this.priceMultiplier));
        ben3.setCount(Mth.clamp(integer2 + integer3 + this.specialPriceDiff, 1, this.baseCostA.getItem().getMaxStackSize()));
        return ben3;
    }
    
    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 jt2 = new CompoundTag();
        jt2.put("buy", this.baseCostA.save(new CompoundTag()));
        jt2.put("sell", this.result.save(new CompoundTag()));
        jt2.put("buyB", this.costB.save(new CompoundTag()));
        jt2.putInt("uses", this.uses);
        jt2.putInt("maxUses", this.maxUses);
        jt2.putBoolean("rewardExp", this.rewardExp);
        jt2.putInt("xp", this.xp);
        jt2.putFloat("priceMultiplier", this.priceMultiplier);
        jt2.putInt("specialPrice", this.specialPriceDiff);
        jt2.putInt("demand", this.demand);
        return jt2;
    }
    
    public boolean satisfiedBy(final ItemStack ben1, final ItemStack ben2) {
        return this.isRequiredItem(ben1, this.getCostA()) && ben1.getCount() >= this.getCostA().getCount() && this.isRequiredItem(ben2, this.costB) && ben2.getCount() >= this.costB.getCount();
    }
    
    private boolean isRequiredItem(final ItemStack ben1, final ItemStack ben2) {
        if (ben2.isEmpty() && ben1.isEmpty()) {
            return true;
        }
        final ItemStack ben3 = ben1.copy();
        if (ben3.getItem().canBeDepleted()) {
            ben3.setDamageValue(ben3.getDamageValue());
        }
        return ItemStack.isSame(ben3, ben2) && (!ben2.hasTag() || (ben3.hasTag() && NbtUtils.compareNbt(ben2.getTag(), ben3.getTag(), false)));
    }
    
    public boolean take(final ItemStack ben1, final ItemStack ben2) {
        if (!this.satisfiedBy(ben1, ben2)) {
            return false;
        }
        ben1.shrink(this.getCostA().getCount());
        if (!this.getCostB().isEmpty()) {
            ben2.shrink(this.getCostB().getCount());
        }
        return true;
    }
}
