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

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

import java.util.Iterator;
import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
import java.util.Comparator;
import com.hypixel.hytale.common.util.StringCompareUtil;
import java.util.Locale;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.List;
import java.nio.file.Path;
import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.BrushConfigCommandExecutor;
import com.hypixel.hytale.builtin.buildertools.PrototypePlayerBuilderToolSettings;
import java.util.UUID;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.builtin.buildertools.tooloperations.ToolOperation;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.builtin.buildertools.scriptedbrushes.ScriptedBrushAsset;
import com.hypixel.hytale.server.core.entity.entities.Player;
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.server.core.ui.browser.FileListProvider;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.ui.browser.ServerFileBrowser;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserEventData;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;

public class ScriptedBrushPage extends InteractiveCustomUIPage<FileBrowserEventData>
{
    @Nonnull
    private final ServerFileBrowser browser;
    
    public ScriptedBrushPage(@Nonnull final PlayerRef playerRef) {
        super(playerRef, CustomPageLifetime.CanDismiss, FileBrowserEventData.CODEC);
        final FileBrowserConfig config = FileBrowserConfig.builder().listElementId("#FileList").searchInputId("#SearchInput").enableRootSelector(false).enableSearch(true).enableDirectoryNav(false).maxResults(50).customProvider(new ScriptedBrushListProvider()).build();
        this.browser = new ServerFileBrowser(config);
    }
    
    @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/ScriptedBrushListPage.ui");
        commandBuilder.set("#RootSelector.Visible", false);
        this.browser.buildSearchInput(commandBuilder, eventBuilder);
        this.browser.buildFileList(commandBuilder, eventBuilder);
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final FileBrowserEventData data) {
        if (this.browser.handleEvent(data)) {
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.browser.buildFileList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        final String brushName = data.getFile();
        if (brushName != null) {
            this.handleBrushSelection(ref, store, brushName);
        }
    }
    
    private void handleBrushSelection(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final String brushName) {
        final Player playerComponent = store.getComponent(ref, Player.getComponentType());
        assert playerComponent != null;
        final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
        assert playerRefComponent != null;
        final ScriptedBrushAsset scriptedBrushAsset = ScriptedBrushAsset.get(brushName);
        if (scriptedBrushAsset == null) {
            playerRefComponent.sendMessage(Message.translation("server.commands.brushConfig.load.error.notFound").param("name", brushName));
            this.sendUpdate();
            return;
        }
        final UUID playerUUID = playerRefComponent.getUuid();
        final PrototypePlayerBuilderToolSettings prototypeSettings = ToolOperation.getOrCreatePrototypeSettings(playerUUID);
        final BrushConfigCommandExecutor brushConfigCommandExecutor = prototypeSettings.getBrushConfigCommandExecutor();
        try {
            scriptedBrushAsset.loadIntoExecutor(brushConfigCommandExecutor);
            prototypeSettings.setCurrentlyLoadedBrushConfigName(scriptedBrushAsset.getId());
            prototypeSettings.setUsePrototypeBrushConfigurations(true);
            playerComponent.getPageManager().setPage(ref, store, Page.None);
            playerRefComponent.sendMessage(Message.translation("server.commands.brushConfig.loaded").param("name", scriptedBrushAsset.getId()));
        }
        catch (final Exception e) {
            playerRefComponent.sendMessage(Message.translation("server.commands.brushConfig.load.error.loadFailed").param("name", brushName).param("error", (e.getMessage() != null) ? e.getMessage() : "Unknown error"));
            this.sendUpdate();
        }
    }
    
    private static class ScriptedBrushListProvider implements FileListProvider
    {
        @Nonnull
        @Override
        public List<FileEntry> getFiles(@Nonnull final Path currentDir, @Nonnull final String searchQuery) {
            final DefaultAssetMap<String, ScriptedBrushAsset> assetMap = ScriptedBrushAsset.getAssetMap();
            if (searchQuery.isEmpty()) {
                final String name;
                return assetMap.getAssetMap().keySet().stream().sorted().map(name -> new FileEntry(name, false)).collect((Collector<? super Object, ?, List<FileEntry>>)Collectors.toList());
            }
            final List<FileEntry> results = new ObjectArrayList<FileEntry>();
            final Iterator<String> iterator = assetMap.getAssetMap().keySet().iterator();
            while (iterator.hasNext()) {
                final String name = iterator.next();
                final int score = StringCompareUtil.getFuzzyDistance(name, searchQuery, Locale.ENGLISH);
                if (score > 0) {
                    results.add(new FileEntry(name, name, false, false, score));
                }
            }
            results.sort(Comparator.comparingInt(FileEntry::matchScore).reversed());
            if (results.size() > 50) {
                return results.subList(0, 50);
            }
            return results;
        }
    }
}
