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

package com.hypixel.hytale.builtin.adventure.npcobjectives;

import com.hypixel.hytale.server.core.universe.world.World;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.adventure.objectives.config.task.UseEntityObjectiveTaskAsset;
import com.hypixel.hytale.builtin.adventure.objectives.task.ObjectiveTask;
import com.hypixel.hytale.builtin.adventure.objectives.Objective;
import java.util.Iterator;
import com.hypixel.hytale.builtin.adventure.objectives.ObjectiveDataStore;
import com.hypixel.hytale.builtin.adventure.objectives.task.UseEntityObjectiveTask;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import java.util.Set;
import java.util.Map;
import java.util.UUID;
import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn;
import com.hypixel.hytale.server.spawning.assets.spawnmarker.config.SpawnMarker;
import com.hypixel.hytale.assetstore.AssetRegistry;
import com.hypixel.hytale.builtin.adventure.objectives.config.ObjectiveAsset;
import com.hypixel.hytale.builtin.adventure.npcobjectives.npc.builders.BuilderSensorHasTask;
import com.hypixel.hytale.builtin.adventure.npcobjectives.npc.builders.BuilderActionStartObjective;
import com.hypixel.hytale.server.npc.asset.builder.Builder;
import java.util.function.Supplier;
import com.hypixel.hytale.builtin.adventure.npcobjectives.npc.builders.BuilderActionCompleteTask;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.builtin.adventure.npcobjectives.systems.KillTrackerSystem;
import com.hypixel.hytale.component.system.ISystem;
import com.hypixel.hytale.builtin.adventure.npcobjectives.systems.SpawnBeaconCheckRemovalSystem;
import com.hypixel.hytale.builtin.adventure.npcobjectives.task.KillNPCObjectiveTask;
import com.hypixel.hytale.builtin.adventure.npcobjectives.assets.KillObjectiveTaskAsset;
import com.hypixel.hytale.builtin.adventure.npcobjectives.task.BountyObjectiveTask;
import com.hypixel.hytale.builtin.adventure.npcobjectives.assets.BountyObjectiveTaskAsset;
import com.hypixel.hytale.builtin.adventure.npcobjectives.task.KillSpawnMarkerObjectiveTask;
import com.hypixel.hytale.builtin.adventure.npcobjectives.assets.KillSpawnMarkerObjectiveTaskAsset;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.builtin.adventure.npcobjectives.task.KillSpawnBeaconObjectiveTask;
import com.hypixel.hytale.builtin.adventure.npcobjectives.assets.KillSpawnBeaconObjectiveTaskAsset;
import com.hypixel.hytale.builtin.adventure.objectives.ObjectivePlugin;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
import com.hypixel.hytale.builtin.adventure.npcobjectives.resources.KillTrackerResource;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.server.core.plugin.JavaPlugin;

public class NPCObjectivesPlugin extends JavaPlugin
{
    protected static NPCObjectivesPlugin instance;
    private ResourceType<EntityStore, KillTrackerResource> killTrackerResourceType;
    
    public static NPCObjectivesPlugin get() {
        return NPCObjectivesPlugin.instance;
    }
    
    public NPCObjectivesPlugin(@Nonnull final JavaPluginInit init) {
        super(init);
    }
    
    @Override
    protected void setup() {
        NPCObjectivesPlugin.instance = this;
        ObjectivePlugin.get().registerTask("KillSpawnBeacon", KillSpawnBeaconObjectiveTaskAsset.class, KillSpawnBeaconObjectiveTaskAsset.CODEC, KillSpawnBeaconObjectiveTask.class, KillSpawnBeaconObjectiveTask.CODEC, KillSpawnBeaconObjectiveTask::new);
        ObjectivePlugin.get().registerTask("KillSpawnMarker", KillSpawnMarkerObjectiveTaskAsset.class, KillSpawnMarkerObjectiveTaskAsset.CODEC, KillSpawnMarkerObjectiveTask.class, KillSpawnMarkerObjectiveTask.CODEC, KillSpawnMarkerObjectiveTask::new);
        ObjectivePlugin.get().registerTask("Bounty", BountyObjectiveTaskAsset.class, BountyObjectiveTaskAsset.CODEC, BountyObjectiveTask.class, BountyObjectiveTask.CODEC, BountyObjectiveTask::new);
        ObjectivePlugin.get().registerTask("KillNPC", KillObjectiveTaskAsset.class, KillObjectiveTaskAsset.CODEC, KillNPCObjectiveTask.class, KillNPCObjectiveTask.CODEC, KillNPCObjectiveTask::new);
        this.getEntityStoreRegistry().registerSystem(new SpawnBeaconCheckRemovalSystem());
        this.killTrackerResourceType = this.getEntityStoreRegistry().registerResource(KillTrackerResource.class, KillTrackerResource::new);
        this.getEntityStoreRegistry().registerSystem((ISystem<EntityStore>)new KillTrackerSystem());
        NPCPlugin.get().registerCoreComponentType("CompleteTask", (Supplier<Builder<Object>>)BuilderActionCompleteTask::new).registerCoreComponentType("StartObjective", (Supplier<Builder<Object>>)BuilderActionStartObjective::new).registerCoreComponentType("HasTask", (Supplier<Builder<Object>>)BuilderSensorHasTask::new);
        AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(SpawnMarker.class);
        AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(BeaconNPCSpawn.class);
        AssetRegistry.getAssetStore(ObjectiveAsset.class).injectLoadsAfter(NPCGroup.class);
    }
    
    public static boolean hasTask(@Nonnull final UUID playerUUID, @Nonnull final UUID npcId, @Nonnull final String taskId) {
        final Map<String, Set<UUID>> entityObjectives = ObjectivePlugin.get().getObjectiveDataStore().getEntityTasksForPlayer(playerUUID);
        return entityObjectives != null && entityObjectives.get(taskId) != null;
    }
    
    @Nullable
    public static String updateTaskCompletion(@Nonnull final Store<EntityStore> store, @Nonnull final Ref<EntityStore> ref, @Nonnull final PlayerRef playerRef, @Nonnull final UUID npcId, @Nonnull final String taskId) {
        final UUIDComponent uuidComponent = store.getComponent(ref, UUIDComponent.getComponentType());
        assert uuidComponent != null;
        final ObjectiveDataStore objectiveDataStore = ObjectivePlugin.get().getObjectiveDataStore();
        final Map<String, Set<UUID>> entityObjectiveUUIDs = objectiveDataStore.getEntityTasksForPlayer(uuidComponent.getUuid());
        if (entityObjectiveUUIDs == null) {
            return null;
        }
        final Set<UUID> objectiveUUIDsForTaskId = entityObjectiveUUIDs.get(taskId);
        if (objectiveUUIDsForTaskId == null) {
            return null;
        }
        for (final UUID objectiveUUID : objectiveUUIDsForTaskId) {
            final Objective objective = objectiveDataStore.getObjective(objectiveUUID);
            if (objective == null) {
                continue;
            }
            for (final ObjectiveTask task : objective.getCurrentTasks()) {
                if (task instanceof final UseEntityObjectiveTask useEntityTask) {
                    final UseEntityObjectiveTaskAsset taskAsset = useEntityTask.getAsset();
                    if (taskAsset.getTaskId().equals(taskId)) {
                        if (!useEntityTask.increaseTaskCompletion(store, ref, 1, objective, playerRef, npcId)) {
                            return null;
                        }
                        return taskAsset.getAnimationIdToPlay();
                    }
                }
            }
        }
        return null;
    }
    
    public static void startObjective(@Nonnull final Ref<EntityStore> playerReference, @Nonnull final String taskId, @Nonnull final Store<EntityStore> store) {
        final UUIDComponent uuidComponent = store.getComponent(playerReference, UUIDComponent.getComponentType());
        assert uuidComponent != null;
        final World world = store.getExternalData().getWorld();
        ObjectivePlugin.get().startObjective(taskId, Set.of(uuidComponent.getUuid()), world.getWorldConfig().getUuid(), null, store);
    }
    
    public ResourceType<EntityStore, KillTrackerResource> getKillTrackerResourceType() {
        return this.killTrackerResourceType;
    }
}
