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

package com.hypixel.hytale.builtin.portals.systems.voidevent;

import javax.annotation.Nullable;
import java.util.Iterator;
import com.hypixel.hytale.component.RemoveReason;
import java.util.UUID;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.server.spawning.wrappers.BeaconSpawnWrapper;
import com.hypixel.hytale.math.vector.Vector3d;
import java.util.List;
import com.hypixel.hytale.builtin.portals.components.voidevent.config.InvasionPortalConfig;
import com.hypixel.hytale.builtin.portals.components.voidevent.config.VoidEventConfig;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity;
import com.hypixel.hytale.server.spawning.SpawningPlugin;
import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn;
import com.hypixel.hytale.builtin.portals.integrations.PortalGameplayConfig;
import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.AddReason;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.builtin.portals.components.voidevent.VoidSpawner;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.query.Query;

public final class VoidSpawnerSystems
{
    private static final Query<EntityStore> QUERY;
    
    static {
        QUERY = Query.and(VoidSpawner.getComponentType(), TransformComponent.getComponentType());
    }
    
    public static class Instantiate extends RefSystem<EntityStore>
    {
        @Override
        public void onEntityAdded(@Nonnull final Ref<EntityStore> ref, @Nonnull final AddReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            HytaleLogger.getLogger().at(Level.INFO).log("Adding void spawner...");
            final World world = store.getExternalData().getWorld();
            final PortalGameplayConfig gameplayConfig = world.getGameplayConfig().getPluginConfig().get((Class<? extends PortalGameplayConfig>)PortalGameplayConfig.class);
            final VoidEventConfig voidEventConfig = gameplayConfig.getVoidEvent();
            final InvasionPortalConfig invasionPortalConfig = voidEventConfig.getInvasionPortalConfig();
            final List<String> spawnBeacons = invasionPortalConfig.getSpawnBeaconsList();
            if (spawnBeacons.isEmpty()) {
                HytaleLogger.getLogger().at(Level.WARNING).log("No spawn beacons configured for void spawn in GameplayConfig for portal world (no mobs will spawn during void event)");
                return;
            }
            final VoidSpawner voidSpawner = commandBuffer.getComponent(ref, VoidSpawner.getComponentType());
            final TransformComponent transform = commandBuffer.getComponent(ref, TransformComponent.getComponentType());
            final Vector3d position = transform.getPosition();
            for (int i = 0; i < spawnBeacons.size(); ++i) {
                final String spawnBeacon = spawnBeacons.get(i);
                final Vector3d beaconPos = position.clone().add(0.0, 0.5 + 0.1 * i, 0.0);
                final int beaconAssetId = BeaconNPCSpawn.getAssetMap().getIndexOrDefault(spawnBeacon, -1);
                if (beaconAssetId == -1) {
                    HytaleLogger.getLogger().at(Level.WARNING).log("No asset found for spawn beacon \"" + spawnBeacon + "\" in GameplayConfig for portal world");
                }
                else {
                    final BeaconSpawnWrapper beaconSpawnWrapper = SpawningPlugin.get().getBeaconSpawnWrapper(beaconAssetId);
                    final Holder<EntityStore> spawnBeaconRef = LegacySpawnBeaconEntity.createHolder(beaconSpawnWrapper, beaconPos, transform.getRotation());
                    commandBuffer.addEntity(spawnBeaconRef, AddReason.SPAWN);
                    final UUID beaconUuid = spawnBeaconRef.getComponent(UUIDComponent.getComponentType()).getUuid();
                    voidSpawner.getSpawnBeaconUuids().add(beaconUuid);
                }
            }
            final String onSpawnParticles = invasionPortalConfig.getOnSpawnParticles();
            if (onSpawnParticles != null) {
                ParticleUtil.spawnParticleEffect(onSpawnParticles, position, commandBuffer);
            }
        }
        
        @Override
        public void onEntityRemove(@Nonnull final Ref<EntityStore> ref, @Nonnull final RemoveReason reason, @Nonnull final Store<EntityStore> store, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
            final World world = store.getExternalData().getWorld();
            final VoidSpawner voidSpawnerComponent = commandBuffer.getComponent(ref, VoidSpawner.getComponentType());
            assert voidSpawnerComponent != null;
            for (final UUID spawnBeaconUuid : voidSpawnerComponent.getSpawnBeaconUuids()) {
                final Ref<EntityStore> spawnBeaconRef = world.getEntityStore().getRefFromUUID(spawnBeaconUuid);
                if (spawnBeaconRef != null) {
                    commandBuffer.removeEntity(spawnBeaconRef, RemoveReason.REMOVE);
                }
            }
        }
        
        @Nullable
        @Override
        public Query<EntityStore> getQuery() {
            return VoidSpawnerSystems.QUERY;
        }
    }
}
