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

package com.hypixel.hytale.builtin.buildertools.prefabeditor.ui;

import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.server.core.entity.entities.Player;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.Iterator;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.util.UUID;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.function.ToIntFunction;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import com.hypixel.hytale.common.util.StringCompareUtil;
import java.util.Locale;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditingMetadata;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import javax.annotation.Nonnull;
import com.hypixel.hytale.builtin.buildertools.prefabeditor.PrefabEditSession;
import com.hypixel.hytale.server.core.ui.Value;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class PrefabTeleportPage extends InteractiveCustomUIPage<PageData>
{
    private static final Value<String> BUTTON_HIGHLIGHTED;
    @Nonnull
    private final PrefabEditSession prefabEditSession;
    @Nonnull
    private String searchQuery;
    
    public PrefabTeleportPage(@Nonnull final PlayerRef playerRef, @Nonnull final PrefabEditSession prefabEditSession) {
        super(playerRef, CustomPageLifetime.CanDismiss, PageData.CODEC);
        this.searchQuery = "";
        this.prefabEditSession = prefabEditSession;
    }
    
    @Override
    public void build(@Nonnull final Ref<EntityStore> ref, @Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder, @Nonnull final Store<EntityStore> store) {
        commandBuilder.append("Pages/PrefabTeleportPage.ui");
        eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#SearchInput", EventData.of("@SearchQuery", "#SearchInput.Value"), false);
        this.buildPrefabList(commandBuilder, eventBuilder);
    }
    
    private void buildPrefabList(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        commandBuilder.clear("#FileList");
        final Map<UUID, PrefabEditingMetadata> loadedPrefabs = this.prefabEditSession.getLoadedPrefabMetadata();
        if (loadedPrefabs.isEmpty()) {
            return;
        }
        List<PrefabEditingMetadata> prefabsToDisplay;
        if (!this.searchQuery.isEmpty()) {
            final Object2IntMap<PrefabEditingMetadata> matchScores = new Object2IntOpenHashMap<PrefabEditingMetadata>(loadedPrefabs.size());
            for (final PrefabEditingMetadata metadata : loadedPrefabs.values()) {
                final String fileName = metadata.getPrefabPath().getFileName().toString();
                final String baseName = fileName.endsWith(".prefab.json") ? fileName.substring(0, fileName.length() - ".prefab.json".length()) : fileName;
                final int fuzzyDistance = StringCompareUtil.getFuzzyDistance(baseName, this.searchQuery, Locale.ENGLISH);
                if (fuzzyDistance > 0) {
                    matchScores.put(metadata, fuzzyDistance);
                }
            }
            final Stream<Object> stream = matchScores.keySet().stream();
            final Object2IntMap<PrefabEditingMetadata> obj = matchScores;
            Objects.requireNonNull((Object2IntOpenHashMap)obj);
            prefabsToDisplay = stream.sorted(Comparator.comparingInt(obj::getInt).reversed()).collect((Collector<? super Object, ?, List<PrefabEditingMetadata>>)Collectors.toList());
        }
        else {
            prefabsToDisplay = loadedPrefabs.values().stream().sorted(Comparator.comparing(m -> m.getPrefabPath().getFileName().toString().toLowerCase())).collect((Collector<? super PrefabEditingMetadata, ?, List<PrefabEditingMetadata>>)Collectors.toList());
        }
        int buttonIndex = 0;
        for (PrefabEditingMetadata metadata : prefabsToDisplay) {
            final Path prefabPath = metadata.getPrefabPath();
            final String fileName2 = prefabPath.getFileName().toString();
            final String displayName = fileName2.endsWith(".prefab.json") ? fileName2.substring(0, fileName2.length() - ".prefab.json".length()) : fileName2;
            commandBuilder.append("#FileList", "Pages/BasicTextButton.ui");
            commandBuilder.set("#FileList[" + buttonIndex + "].Text", displayName);
            commandBuilder.set("#FileList[" + buttonIndex + "].Style", PrefabTeleportPage.BUTTON_HIGHLIGHTED);
            commandBuilder.set("#FileList[" + buttonIndex + "].TooltipText", prefabPath.toString());
            eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#FileList[" + buttonIndex, EventData.of("PrefabUuid", metadata.getUuid().toString()));
            ++buttonIndex;
        }
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final PageData data) {
        if (data.getSearchQuery() != null) {
            this.searchQuery = data.getSearchQuery().trim().toLowerCase();
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.buildPrefabList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        if (data.getPrefabUuid() != null) {
            try {
                final UUID prefabUuid = UUID.fromString(data.getPrefabUuid());
                final PrefabEditingMetadata metadata = this.prefabEditSession.getLoadedPrefabMetadata().get(prefabUuid);
                if (metadata != null) {
                    final Player playerComponent = store.getComponent(ref, Player.getComponentType());
                    assert playerComponent != null;
                    final Vector3i minPoint = metadata.getMinPoint();
                    final Vector3i maxPoint = metadata.getMaxPoint();
                    final int centerX = (minPoint.x + maxPoint.x) / 2;
                    final int centerZ = (minPoint.z + maxPoint.z) / 2;
                    final World world = store.getExternalData().getWorld();
                    final WorldChunk worldChunk = world.getChunkIfInMemory(ChunkUtil.indexChunkFromBlock(centerX, centerZ));
                    final int teleportY = (worldChunk != null) ? (worldChunk.getHeight(centerX, centerZ) + 8) : (maxPoint.y + 8);
                    final Vector3d teleportPosition = new Vector3d(centerX + 0.5, teleportY, centerZ + 0.5);
                    store.addComponent(ref, Teleport.getComponentType(), Teleport.createForPlayer(teleportPosition, new Vector3f()));
                    playerComponent.getPageManager().setPage(ref, store, Page.None);
                }
            }
            catch (final IllegalArgumentException ex) {}
        }
    }
    
    static {
        BUTTON_HIGHLIGHTED = Value.ref("Pages/BasicTextButton.ui", "SelectedLabelStyle");
    }
    
    public static class PageData
    {
        static final String KEY_SEARCH_QUERY = "@SearchQuery";
        static final String KEY_PREFAB_UUID = "PrefabUuid";
        public static final BuilderCodec<PageData> CODEC;
        private String searchQuery;
        private String prefabUuid;
        
        public String getSearchQuery() {
            return this.searchQuery;
        }
        
        public String getPrefabUuid() {
            return this.prefabUuid;
        }
        
        static {
            CODEC = BuilderCodec.builder(PageData.class, PageData::new).addField(new KeyedCodec<String>("@SearchQuery", Codec.STRING), (entry, s) -> entry.searchQuery = s, entry -> entry.searchQuery).addField(new KeyedCodec("PrefabUuid", Codec.STRING), (entry, s) -> entry.prefabUuid = s, entry -> entry.prefabUuid).build();
        }
    }
}
