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.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 xd, final Villager axw) {
        return BehaviorUtils.targetIsValid(axw.getBrain(), MemoryModuleType.INTERACTION_TARGET, EntityType.VILLAGER);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel xd, final Villager axw, final long long3) {
        return this.checkExtraStartConditions(xd, axw);
    }
    
    @Override
    protected void start(final ServerLevel xd, final Villager axw, final long long3) {
        final Villager axw2 = axw.getBrain().<Villager>getMemory((MemoryModuleType<Villager>)MemoryModuleType.INTERACTION_TARGET).get();
        BehaviorUtils.lockGazeAndWalkToEachOther(axw, axw2);
        this.trades = figureOutWhatIAmWillingToTrade(axw, axw2);
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        final Villager axw2 = axw.getBrain().<Villager>getMemory((MemoryModuleType<Villager>)MemoryModuleType.INTERACTION_TARGET).get();
        if (axw.distanceToSqr(axw2) > 5.0) {
            return;
        }
        BehaviorUtils.lockGazeAndWalkToEachOther(axw, axw2);
        axw.gossip(axw2, long3);
        if (axw.hasExcessFood() && (axw.getVillagerData().getProfession() == VillagerProfession.FARMER || axw2.wantsMoreFood())) {
            throwHalfStack(axw, Villager.FOOD_POINTS.keySet(), axw2);
        }
        if (!this.trades.isEmpty() && axw.getInventory().hasAnyOf(this.trades)) {
            throwHalfStack(axw, this.trades, axw2);
        }
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        axw.getBrain().<LivingEntity>eraseMemory(MemoryModuleType.INTERACTION_TARGET);
    }
    
    private static Set<Item> figureOutWhatIAmWillingToTrade(final Villager axw1, final Villager axw2) {
        final ImmutableSet<Item> immutableSet3 = axw2.getVillagerData().getProfession().getRequestedItems();
        final ImmutableSet<Item> immutableSet4 = axw1.getVillagerData().getProfession().getRequestedItems();
        return immutableSet3.stream().filter(bei -> !immutableSet4.contains(bei)).collect(Collectors.toSet());
    }
    
    private static void throwHalfStack(final Villager axw, final Set<Item> set, final LivingEntity akz) {
        final SimpleContainer ajq4 = axw.getInventory();
        ItemStack ben5 = ItemStack.EMPTY;
        for (int integer6 = 0; integer6 < ajq4.getContainerSize(); ++integer6) {
            final ItemStack ben6 = ajq4.getItem(integer6);
            if (!ben6.isEmpty()) {
                final Item bei8 = ben6.getItem();
                if (set.contains(bei8)) {
                    int integer7;
                    if (ben6.getCount() > ben6.getMaxStackSize() / 2) {
                        integer7 = ben6.getCount() / 2;
                    }
                    else {
                        if (ben6.getCount() <= 24) {
                            continue;
                        }
                        integer7 = ben6.getCount() - 24;
                    }
                    ben6.shrink(integer7);
                    ben5 = new ItemStack(bei8, integer7);
                    break;
                }
            }
        }
        if (!ben5.isEmpty()) {
            BehaviorUtils.throwItem(axw, ben5, akz);
        }
    }
}
