// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.adventure.objectives.task;

import com.hypixel.hytale.server.core.event.events.entity.EntityEvent;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.ObjectiveTaskAsset;
import com.hypixel.hytale.server.core.inventory.container.CombinedItemContainer;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.util.Iterator;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.BlockTagOrItemIdField;
import com.hypixel.hytale.server.core.universe.Universe;
import javax.annotation.Nullable;
import java.util.UUID;
import java.util.Set;
import com.hypixel.hytale.builtin.adventure.objectives.transaction.RegistrationTransactionRecord;
import com.hypixel.hytale.event.IBaseEvent;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.builtin.adventure.objectives.transaction.TransactionRecord;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.builtin.adventure.objectives.Objective;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.CountObjectiveTaskAsset;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.GatherObjectiveTaskAsset;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class GatherObjectiveTask extends CountObjectiveTask
{
    public static final BuilderCodec<GatherObjectiveTask> CODEC;
    
    public GatherObjectiveTask(@Nonnull final GatherObjectiveTaskAsset asset, final int taskSetIndex, final int taskIndex) {
        super(asset, taskSetIndex, taskIndex);
    }
    
    protected GatherObjectiveTask() {
    }
    
    @Nonnull
    @Override
    public GatherObjectiveTaskAsset getAsset() {
        return (GatherObjectiveTaskAsset)super.getAsset();
    }
    
    @Nullable
    @Override
    protected TransactionRecord[] setup0(@Nonnull final Objective objective, @Nonnull final World world, @Nonnull final Store<EntityStore> store) {
        final Set<UUID> participatingPlayers = objective.getPlayerUUIDs();
        final int countItem = this.countObjectiveItemInInventories(participatingPlayers, store);
        if (this.areTaskConditionsFulfilled(null, null, participatingPlayers)) {
            this.count = MathUtil.clamp(countItem, 0, this.getAsset().getCount());
            if (this.checkCompletion()) {
                this.consumeTaskConditions(null, null, participatingPlayers);
                this.complete = true;
                return null;
            }
        }
        this.eventRegistry.register((Class<? super IBaseEvent>)LivingEntityInventoryChangeEvent.class, world.getName(), event -> {
            final LivingEntity livingEntity = ((EntityEvent<LivingEntity, KeyType>)event).getEntity();
            if (!(livingEntity instanceof Player)) {
                return;
            }
            else {
                final Ref<EntityStore> ref = livingEntity.getReference();
                if (ref == null || !ref.isValid()) {
                    return;
                }
                else {
                    final World refWorld = store.getExternalData().getWorld();
                    refWorld.execute(() -> {
                        if (!(!ref.isValid())) {
                            final UUIDComponent uuidComponent = store.getComponent(ref, UUIDComponent.getComponentType());
                            if (uuidComponent != null) {
                                final Set<UUID> activePlayerUUIDs = objective.getActivePlayerUUIDs();
                                if (!(!activePlayerUUIDs.contains(uuidComponent.getUuid()))) {
                                    final int count = this.countObjectiveItemInInventories(activePlayerUUIDs, store);
                                    this.setTaskCompletion(store, ref, count, objective);
                                }
                            }
                        }
                    });
                    return;
                }
            }
        });
        return RegistrationTransactionRecord.wrap(this.eventRegistry);
    }
    
    private int countObjectiveItemInInventories(@Nonnull final Set<UUID> participatingPlayers, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        int count = 0;
        final BlockTagOrItemIdField blockTypeOrSet = this.getAsset().getBlockTagOrItemIdField();
        for (final UUID playerUUID : participatingPlayers) {
            final PlayerRef playerRefComponent = Universe.get().getPlayer(playerUUID);
            if (playerRefComponent == null) {
                continue;
            }
            final Ref<EntityStore> playerRef = playerRefComponent.getReference();
            if (playerRef == null) {
                continue;
            }
            if (!playerRef.isValid()) {
                continue;
            }
            final Player playerComponent = componentAccessor.getComponent(playerRef, Player.getComponentType());
            assert playerComponent != null;
            final CombinedItemContainer inventory = playerComponent.getInventory().getCombinedHotbarFirst();
            count += inventory.countItemStacks(itemStack -> blockTypeOrSet.isBlockTypeIncluded(itemStack.getItemId()));
        }
        return count;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "GatherObjectiveTask{} " + super.toString();
    }
    
    static {
        CODEC = BuilderCodec.builder(GatherObjectiveTask.class, GatherObjectiveTask::new, CountObjectiveTask.CODEC).build();
    }
}
