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.world.entity.Entity;
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.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 xd, final Villager axw) {
        if (!this.isHeroVisible(axw)) {
            return false;
        }
        if (this.timeUntilNextGift > 0) {
            --this.timeUntilNextGift;
            return false;
        }
        return true;
    }
    
    @Override
    protected void start(final ServerLevel xd, final Villager axw, final long long3) {
        this.giftGivenDuringThisRun = false;
        this.timeSinceStart = long3;
        final Player ayj6 = this.getNearestTargetableHero(axw).get();
        axw.getBrain().<LivingEntity>setMemory(MemoryModuleType.INTERACTION_TARGET, ayj6);
        BehaviorUtils.lookAtEntity(axw, ayj6);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel xd, final Villager axw, final long long3) {
        return this.isHeroVisible(axw) && !this.giftGivenDuringThisRun;
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        final Player ayj6 = this.getNearestTargetableHero(axw).get();
        BehaviorUtils.lookAtEntity(axw, ayj6);
        if (this.isWithinThrowingDistance(axw, ayj6)) {
            if (long3 - this.timeSinceStart > 20L) {
                this.throwGift(axw, ayj6);
                this.giftGivenDuringThisRun = true;
            }
        }
        else {
            BehaviorUtils.walkToEntity(axw, ayj6, 5);
        }
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        this.timeUntilNextGift = calculateTimeUntilNextGift(xd);
        axw.getBrain().<LivingEntity>eraseMemory(MemoryModuleType.INTERACTION_TARGET);
        axw.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        axw.getBrain().<PositionWrapper>eraseMemory(MemoryModuleType.LOOK_TARGET);
    }
    
    private void throwGift(final Villager axw, final LivingEntity akz) {
        final List<ItemStack> list4 = this.getItemToThrow(axw);
        for (final ItemStack ben6 : list4) {
            BehaviorUtils.throwItem(axw, ben6, akz);
        }
    }
    
    private List<ItemStack> getItemToThrow(final Villager axw) {
        if (axw.isBaby()) {
            return ImmutableList.<ItemStack>of(new ItemStack(Items.POPPY));
        }
        final VillagerProfession axz3 = axw.getVillagerData().getProfession();
        if (GiveGiftToHero.gifts.containsKey(axz3)) {
            final LootTable csa4 = axw.level.getServer().getLootTables().get(GiveGiftToHero.gifts.get(axz3));
            final LootContext.Builder a5 = new LootContext.Builder((ServerLevel)axw.level).<BlockPos>withParameter(LootContextParams.BLOCK_POS, new BlockPos(axw)).<Entity>withParameter(LootContextParams.THIS_ENTITY, axw).withRandom(axw.getRandom());
            return csa4.getRandomItems(a5.create(LootContextParamSets.GIFT));
        }
        return ImmutableList.<ItemStack>of(new ItemStack(Items.WHEAT_SEEDS));
    }
    
    private boolean isHeroVisible(final Villager axw) {
        return this.getNearestTargetableHero(axw).isPresent();
    }
    
    private Optional<Player> getNearestTargetableHero(final Villager axw) {
        return axw.getBrain().<Player>getMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER).filter(this::isHero);
    }
    
    private boolean isHero(final Player ayj) {
        return ayj.hasEffect(MobEffects.HERO_OF_THE_VILLAGE);
    }
    
    private boolean isWithinThrowingDistance(final Villager axw, final Player ayj) {
        final BlockPos fk4 = new BlockPos(ayj);
        final BlockPos fk5 = new BlockPos(axw);
        return fk5.closerThan(fk4, 5.0);
    }
    
    private static int calculateTimeUntilNextGift(final ServerLevel xd) {
        return 600 + xd.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);
        });
    }
}
