package net.minecraft.world.entity.ai.behavior;

import net.minecraft.Util;
import com.google.common.collect.Maps;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import java.util.HashMap;
import net.minecraft.core.Vec3i;
import net.minecraft.world.effect.MobEffects;
import java.util.function.Predicate;
import java.util.Optional;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootContext;
import com.google.common.collect.ImmutableList;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.Items;
import java.util.Iterator;
import java.util.List;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.npc.VillagerProfession;
import java.util.Map;
import net.minecraft.world.entity.npc.Villager;

public class GiveGiftToHero extends Behavior<Villager> {
    private static final Map<VillagerProfession, ResourceLocation> gifts;
    private int timeUntilNextGift;
    private boolean giftGivenDuringThisRun;
    private long timeSinceStart;
    
    public GiveGiftToHero(final int integer) {
        super(ImmutableMap.<MemoryModuleType<WalkTarget>, MemoryStatus>of(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<WalkTarget>)MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<WalkTarget>)MemoryModuleType.INTERACTION_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<WalkTarget>)MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryStatus.VALUE_PRESENT), integer);
        this.timeUntilNextGift = 600;
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final Villager bdp) {
        if (!this.isHeroVisible(bdp)) {
            return false;
        }
        if (this.timeUntilNextGift > 0) {
            --this.timeUntilNextGift;
            return false;
        }
        return true;
    }
    
    @Override
    protected void start(final ServerLevel zd, final Villager bdp, final long long3) {
        this.giftGivenDuringThisRun = false;
        this.timeSinceStart = long3;
        final Player bec6 = this.getNearestTargetableHero(bdp).get();
        bdp.getBrain().<LivingEntity>setMemory(MemoryModuleType.INTERACTION_TARGET, bec6);
        BehaviorUtils.lookAtEntity(bdp, bec6);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel zd, final Villager bdp, final long long3) {
        return this.isHeroVisible(bdp) && !this.giftGivenDuringThisRun;
    }
    
    @Override
    protected void tick(final ServerLevel zd, final Villager bdp, final long long3) {
        final Player bec6 = this.getNearestTargetableHero(bdp).get();
        BehaviorUtils.lookAtEntity(bdp, bec6);
        if (this.isWithinThrowingDistance(bdp, bec6)) {
            if (long3 - this.timeSinceStart > 20L) {
                this.throwGift(bdp, bec6);
                this.giftGivenDuringThisRun = true;
            }
        }
        else {
            BehaviorUtils.setWalkAndLookTargetMemories(bdp, bec6, 0.5f, 5);
        }
    }
    
    @Override
    protected void tick(final ServerLevel zd, final Villager bdp, final long long3) {
        this.timeUntilNextGift = calculateTimeUntilNextGift(zd);
        bdp.getBrain().<LivingEntity>eraseMemory(MemoryModuleType.INTERACTION_TARGET);
        bdp.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        bdp.getBrain().<PositionTracker>eraseMemory(MemoryModuleType.LOOK_TARGET);
    }
    
    private void throwGift(final Villager bdp, final LivingEntity aoy) {
        final List<ItemStack> list4 = this.getItemToThrow(bdp);
        for (final ItemStack bki6 : list4) {
            BehaviorUtils.throwItem(bdp, bki6, aoy.position());
        }
    }
    
    private List<ItemStack> getItemToThrow(final Villager bdp) {
        if (bdp.isBaby()) {
            return ImmutableList.<ItemStack>of(new ItemStack(Items.POPPY));
        }
        final VillagerProfession bds3 = bdp.getVillagerData().getProfession();
        if (GiveGiftToHero.gifts.containsKey(bds3)) {
            final LootTable daw4 = bdp.level.getServer().getLootTables().get(GiveGiftToHero.gifts.get(bds3));
            final LootContext.Builder a5 = new LootContext.Builder((ServerLevel)bdp.level).<BlockPos>withParameter(LootContextParams.BLOCK_POS, bdp.blockPosition()).<Entity>withParameter(LootContextParams.THIS_ENTITY, bdp).withRandom(bdp.getRandom());
            return daw4.getRandomItems(a5.create(LootContextParamSets.GIFT));
        }
        return ImmutableList.<ItemStack>of(new ItemStack(Items.WHEAT_SEEDS));
    }
    
    private boolean isHeroVisible(final Villager bdp) {
        return this.getNearestTargetableHero(bdp).isPresent();
    }
    
    private Optional<Player> getNearestTargetableHero(final Villager bdp) {
        return bdp.getBrain().<Player>getMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER).filter(this::isHero);
    }
    
    private boolean isHero(final Player bec) {
        return bec.hasEffect(MobEffects.HERO_OF_THE_VILLAGE);
    }
    
    private boolean isWithinThrowingDistance(final Villager bdp, final Player bec) {
        final BlockPos fu4 = bec.blockPosition();
        final BlockPos fu5 = bdp.blockPosition();
        return fu5.closerThan(fu4, 5.0);
    }
    
    private static int calculateTimeUntilNextGift(final ServerLevel zd) {
        return 600 + zd.random.nextInt(6001);
    }
    
    static {
        gifts = Util.<Map<VillagerProfession, ResourceLocation>>make(Maps.newHashMap(), hashMap -> {
            hashMap.put(VillagerProfession.ARMORER, BuiltInLootTables.ARMORER_GIFT);
            hashMap.put(VillagerProfession.BUTCHER, BuiltInLootTables.BUTCHER_GIFT);
            hashMap.put(VillagerProfession.CARTOGRAPHER, BuiltInLootTables.CARTOGRAPHER_GIFT);
            hashMap.put(VillagerProfession.CLERIC, BuiltInLootTables.CLERIC_GIFT);
            hashMap.put(VillagerProfession.FARMER, BuiltInLootTables.FARMER_GIFT);
            hashMap.put(VillagerProfession.FISHERMAN, BuiltInLootTables.FISHERMAN_GIFT);
            hashMap.put(VillagerProfession.FLETCHER, BuiltInLootTables.FLETCHER_GIFT);
            hashMap.put(VillagerProfession.LEATHERWORKER, BuiltInLootTables.LEATHERWORKER_GIFT);
            hashMap.put(VillagerProfession.LIBRARIAN, BuiltInLootTables.LIBRARIAN_GIFT);
            hashMap.put(VillagerProfession.MASON, BuiltInLootTables.MASON_GIFT);
            hashMap.put(VillagerProfession.SHEPHERD, BuiltInLootTables.SHEPHERD_GIFT);
            hashMap.put(VillagerProfession.TOOLSMITH, BuiltInLootTables.TOOLSMITH_GIFT);
            hashMap.put(VillagerProfession.WEAPONSMITH, BuiltInLootTables.WEAPONSMITH_GIFT);
        });
    }
}
