package net.minecraft.world.entity.npc;

import net.minecraft.core.Position;
import net.minecraft.world.phys.Vec3;
import java.util.EnumSet;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.item.Item;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.ExperienceOrb;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.entity.Entity;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.AgableMob;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.InteractGoal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.MoveTowardsRestrictionGoal;
import net.minecraft.world.entity.ai.goal.LookAtTradingPlayerGoal;
import net.minecraft.world.entity.ai.goal.PanicGoal;
import net.minecraft.world.entity.monster.Illusioner;
import net.minecraft.world.entity.monster.Pillager;
import net.minecraft.world.entity.monster.Vex;
import net.minecraft.world.entity.monster.Vindicator;
import net.minecraft.world.entity.monster.Evoker;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal;
import net.minecraft.world.entity.monster.Zombie;
import net.minecraft.world.entity.ai.goal.TradeWithPlayerGoal;
import net.minecraft.world.entity.ai.goal.UseItemGoal;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;

public class WanderingTrader extends AbstractVillager {
    @Nullable
    private BlockPos wanderTarget;
    private int despawnDelay;
    
    public WanderingTrader(final EntityType<? extends WanderingTrader> aku, final Level bjw) {
        super(aku, bjw);
        this.forcedLoading = true;
    }
    
    @Override
    protected void registerGoals() {
        this.goalSelector.addGoal(0, new FloatGoal(this));
        this.goalSelector.addGoal(0, new UseItemGoal<>(this, PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEvents.WANDERING_TRADER_DISAPPEARED, ayc -> !this.level.isDay() && !ayc.isInvisible()));
        this.goalSelector.addGoal(0, new UseItemGoal<>(this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, ayc -> this.level.isDay() && ayc.isInvisible()));
        this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Zombie.class, 8.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Evoker.class, 12.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Vindicator.class, 8.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Vex.class, 8.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Pillager.class, 15.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Illusioner.class, 12.0f, 0.5, 0.5));
        this.goalSelector.addGoal(1, new PanicGoal(this, 0.5));
        this.goalSelector.addGoal(1, new LookAtTradingPlayerGoal(this));
        this.goalSelector.addGoal(2, new WanderToPositionGoal(this, 2.0, 0.35));
        this.goalSelector.addGoal(4, new MoveTowardsRestrictionGoal(this, 0.35));
        this.goalSelector.addGoal(8, new WaterAvoidingRandomStrollGoal(this, 0.35));
        this.goalSelector.addGoal(9, new InteractGoal(this, Player.class, 3.0f, 1.0f));
        this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0f));
    }
    
    @Nullable
    @Override
    public AgableMob getBreedOffspring(final AgableMob ako) {
        return null;
    }
    
    @Override
    public boolean showProgressBar() {
        return false;
    }
    
    @Override
    public boolean mobInteract(final Player ayj, final InteractionHand ajk) {
        final ItemStack ben4 = ayj.getItemInHand(ajk);
        final boolean boolean5 = ben4.getItem() == Items.NAME_TAG;
        if (boolean5) {
            ben4.interactEnemy(ayj, this, ajk);
            return true;
        }
        if (ben4.getItem() == Items.VILLAGER_SPAWN_EGG || !this.isAlive() || this.isTrading() || this.isBaby()) {
            return super.mobInteract(ayj, ajk);
        }
        if (ajk == InteractionHand.MAIN_HAND) {
            ayj.awardStat(Stats.TALKED_TO_VILLAGER);
        }
        if (this.getOffers().isEmpty()) {
            return super.mobInteract(ayj, ajk);
        }
        if (!this.level.isClientSide) {
            this.setTradingPlayer(ayj);
            this.openTradingScreen(ayj, this.getDisplayName(), 1);
        }
        return true;
    }
    
    @Override
    protected void updateTrades() {
        final VillagerTrades.ItemListing[] arr2 = (VillagerTrades.ItemListing[])VillagerTrades.WANDERING_TRADER_TRADES.get(1);
        final VillagerTrades.ItemListing[] arr3 = (VillagerTrades.ItemListing[])VillagerTrades.WANDERING_TRADER_TRADES.get(2);
        if (arr2 == null || arr3 == null) {
            return;
        }
        final MerchantOffers bja4 = this.getOffers();
        this.addOffersFromItemListings(bja4, arr2, 5);
        final int integer5 = this.random.nextInt(arr3.length);
        final VillagerTrades.ItemListing f6 = arr3[integer5];
        final MerchantOffer biz7 = f6.getOffer(this, this.random);
        if (biz7 != null) {
            bja4.add(biz7);
        }
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag jt) {
        super.addAdditionalSaveData(jt);
        jt.putInt("DespawnDelay", this.despawnDelay);
        if (this.wanderTarget != null) {
            jt.put("WanderTarget", NbtUtils.writeBlockPos(this.wanderTarget));
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag jt) {
        super.readAdditionalSaveData(jt);
        if (jt.contains("DespawnDelay", 99)) {
            this.despawnDelay = jt.getInt("DespawnDelay");
        }
        if (jt.contains("WanderTarget")) {
            this.wanderTarget = NbtUtils.readBlockPos(jt.getCompound("WanderTarget"));
        }
        this.setAge(Math.max(0, this.getAge()));
    }
    
    @Override
    public boolean removeWhenFarAway(final double double1) {
        return false;
    }
    
    @Override
    protected void rewardTradeXp(final MerchantOffer biz) {
        if (biz.shouldRewardExp()) {
            final int integer3 = 3 + this.random.nextInt(4);
            this.level.addFreshEntity(new ExperienceOrb(this.level, this.getX(), this.getY() + 0.5, this.getZ(), integer3));
        }
    }
    
    @Override
    protected SoundEvent getAmbientSound() {
        if (this.isTrading()) {
            return SoundEvents.WANDERING_TRADER_TRADE;
        }
        return SoundEvents.WANDERING_TRADER_AMBIENT;
    }
    
    @Override
    protected SoundEvent getHurtSound(final DamageSource ajz) {
        return SoundEvents.WANDERING_TRADER_HURT;
    }
    
    @Override
    protected SoundEvent getDeathSound() {
        return SoundEvents.WANDERING_TRADER_DEATH;
    }
    
    @Override
    protected SoundEvent getDrinkingSound(final ItemStack ben) {
        final Item bei3 = ben.getItem();
        if (bei3 == Items.MILK_BUCKET) {
            return SoundEvents.WANDERING_TRADER_DRINK_MILK;
        }
        return SoundEvents.WANDERING_TRADER_DRINK_POTION;
    }
    
    @Override
    protected SoundEvent getTradeUpdatedSound(final boolean boolean1) {
        return boolean1 ? SoundEvents.WANDERING_TRADER_YES : SoundEvents.WANDERING_TRADER_NO;
    }
    
    @Override
    public SoundEvent getNotifyTradeSound() {
        return SoundEvents.WANDERING_TRADER_YES;
    }
    
    public void setDespawnDelay(final int integer) {
        this.despawnDelay = integer;
    }
    
    public int getDespawnDelay() {
        return this.despawnDelay;
    }
    
    @Override
    public void aiStep() {
        super.aiStep();
        if (!this.level.isClientSide) {
            this.maybeDespawn();
        }
    }
    
    private void maybeDespawn() {
        if (this.despawnDelay > 0 && !this.isTrading() && --this.despawnDelay == 0) {
            this.remove();
        }
    }
    
    public void setWanderTarget(@Nullable final BlockPos fk) {
        this.wanderTarget = fk;
    }
    
    @Nullable
    private BlockPos getWanderTarget() {
        return this.wanderTarget;
    }
    
    class WanderToPositionGoal extends Goal {
        final WanderingTrader trader;
        final double stopDistance;
        final double speedModifier;
        
        WanderToPositionGoal(final WanderingTrader ayc2, final double double3, final double double4) {
            this.trader = ayc2;
            this.stopDistance = double3;
            this.speedModifier = double4;
            this.setFlags(EnumSet.<Flag>of(Flag.MOVE));
        }
        
        @Override
        public void stop() {
            this.trader.setWanderTarget(null);
            WanderingTrader.this.navigation.stop();
        }
        
        @Override
        public boolean canUse() {
            final BlockPos fk2 = this.trader.getWanderTarget();
            return fk2 != null && this.isTooFarAway(fk2, this.stopDistance);
        }
        
        @Override
        public void tick() {
            final BlockPos fk2 = this.trader.getWanderTarget();
            if (fk2 != null && WanderingTrader.this.navigation.isDone()) {
                if (this.isTooFarAway(fk2, 10.0)) {
                    final Vec3 cvl3 = new Vec3(fk2.getX() - this.trader.getX(), fk2.getY() - this.trader.getY(), fk2.getZ() - this.trader.getZ()).normalize();
                    final Vec3 cvl4 = cvl3.scale(10.0).add(this.trader.getX(), this.trader.getY(), this.trader.getZ());
                    WanderingTrader.this.navigation.moveTo(cvl4.x, cvl4.y, cvl4.z, this.speedModifier);
                }
                else {
                    WanderingTrader.this.navigation.moveTo(fk2.getX(), fk2.getY(), fk2.getZ(), this.speedModifier);
                }
            }
        }
        
        private boolean isTooFarAway(final BlockPos fk, final double double2) {
            return !fk.closerThan(this.trader.position(), double2);
        }
    }
}
