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

import net.minecraft.world.SimpleContainer;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.ItemStack;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.EntityType;
import net.minecraft.server.level.ServerLevel;
import com.google.common.collect.ImmutableSet;
import java.util.Map;
import net.minecraft.world.entity.LivingEntity;
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.world.item.Item;
import java.util.Set;
import net.minecraft.world.entity.npc.Villager;

public class TradeWithVillager extends Behavior<Villager> {
    private Set<Item> trades;
    
    public TradeWithVillager() {
        super(ImmutableMap.<MemoryModuleType<LivingEntity>, MemoryStatus>of(MemoryModuleType.INTERACTION_TARGET, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<LivingEntity>)MemoryModuleType.VISIBLE_LIVING_ENTITIES, MemoryStatus.VALUE_PRESENT));
        this.trades = ImmutableSet.of();
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final Villager bdp) {
        return BehaviorUtils.targetIsValid(bdp.getBrain(), MemoryModuleType.INTERACTION_TARGET, EntityType.VILLAGER);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel zd, final Villager bdp, final long long3) {
        return this.checkExtraStartConditions(zd, bdp);
    }
    
    @Override
    protected void start(final ServerLevel zd, final Villager bdp, final long long3) {
        final Villager bdp2 = bdp.getBrain().<Villager>getMemory((MemoryModuleType<Villager>)MemoryModuleType.INTERACTION_TARGET).get();
        BehaviorUtils.lockGazeAndWalkToEachOther(bdp, bdp2, 0.5f);
        this.trades = figureOutWhatIAmWillingToTrade(bdp, bdp2);
    }
    
    @Override
    protected void tick(final ServerLevel zd, final Villager bdp, final long long3) {
        final Villager bdp2 = bdp.getBrain().<Villager>getMemory((MemoryModuleType<Villager>)MemoryModuleType.INTERACTION_TARGET).get();
        if (bdp.distanceToSqr(bdp2) > 5.0) {
            return;
        }
        BehaviorUtils.lockGazeAndWalkToEachOther(bdp, bdp2, 0.5f);
        bdp.gossip(bdp2, long3);
        if (bdp.hasExcessFood() && (bdp.getVillagerData().getProfession() == VillagerProfession.FARMER || bdp2.wantsMoreFood())) {
            throwHalfStack(bdp, Villager.FOOD_POINTS.keySet(), bdp2);
        }
        if (bdp2.getVillagerData().getProfession() == VillagerProfession.FARMER && bdp.getInventory().countItem(Items.WHEAT) > Items.WHEAT.getMaxStackSize() / 2) {
            throwHalfStack(bdp, ImmutableSet.<Item>of(Items.WHEAT), bdp2);
        }
        if (!this.trades.isEmpty() && bdp.getInventory().hasAnyOf(this.trades)) {
            throwHalfStack(bdp, this.trades, bdp2);
        }
    }
    
    @Override
    protected void tick(final ServerLevel zd, final Villager bdp, final long long3) {
        bdp.getBrain().<LivingEntity>eraseMemory(MemoryModuleType.INTERACTION_TARGET);
    }
    
    private static Set<Item> figureOutWhatIAmWillingToTrade(final Villager bdp1, final Villager bdp2) {
        final ImmutableSet<Item> immutableSet3 = bdp2.getVillagerData().getProfession().getRequestedItems();
        final ImmutableSet<Item> immutableSet4 = bdp1.getVillagerData().getProfession().getRequestedItems();
        return immutableSet3.stream().filter(bke -> !immutableSet4.contains(bke)).collect(Collectors.toSet());
    }
    
    private static void throwHalfStack(final Villager bdp, final Set<Item> set, final LivingEntity aoy) {
        final SimpleContainer anm4 = bdp.getInventory();
        ItemStack bki5 = ItemStack.EMPTY;
        for (int integer6 = 0; integer6 < anm4.getContainerSize(); ++integer6) {
            final ItemStack bki6 = anm4.getItem(integer6);
            if (!bki6.isEmpty()) {
                final Item bke8 = bki6.getItem();
                if (set.contains(bke8)) {
                    int integer7;
                    if (bki6.getCount() > bki6.getMaxStackSize() / 2) {
                        integer7 = bki6.getCount() / 2;
                    }
                    else {
                        if (bki6.getCount() <= 24) {
                            continue;
                        }
                        integer7 = bki6.getCount() - 24;
                    }
                    bki6.shrink(integer7);
                    bki5 = new ItemStack(bke8, integer7);
                    break;
                }
            }
        }
        if (!bki5.isEmpty()) {
            BehaviorUtils.throwItem(bdp, bki5, aoy.position());
        }
    }
}
