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

package com.hypixel.hytale.builtin.buildertools.prefablist;

import java.util.Iterator;
import com.hypixel.hytale.server.core.ui.Value;
import com.hypixel.hytale.server.core.ui.browser.FileListProvider;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
import com.hypixel.hytale.builtin.buildertools.utils.PasteToolUtil;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.entity.entities.Player;
import java.nio.file.Files;
import java.nio.file.LinkOption;
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 it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
import com.hypixel.hytale.server.core.prefab.PrefabStore;
import java.nio.file.Paths;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import java.nio.file.Path;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
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 PrefabPage extends InteractiveCustomUIPage<FileBrowserEventData>
{
    private static final String ASSETS_ROOT_KEY = "Assets";
    @Nonnull
    private final ServerFileBrowser browser;
    @Nonnull
    private final BuilderToolsPlugin.BuilderState builderState;
    @Nonnull
    private final AssetPrefabFileProvider assetProvider;
    private boolean inAssetsRoot;
    @Nonnull
    private Path assetsCurrentDir;
    
    public PrefabPage(@Nonnull final PlayerRef playerRef, final Path defaultRoot, @Nonnull final BuilderToolsPlugin.BuilderState builderState) {
        super(playerRef, CustomPageLifetime.CanDismiss, FileBrowserEventData.CODEC);
        this.inAssetsRoot = true;
        this.assetsCurrentDir = Paths.get("", new String[0]);
        this.builderState = builderState;
        this.assetProvider = new AssetPrefabFileProvider();
        final PrefabStore prefabStore = PrefabStore.get();
        final List<FileBrowserConfig.RootEntry> roots = buildRootEntries(prefabStore);
        final FileBrowserConfig config = FileBrowserConfig.builder().listElementId("#FileList").rootSelectorId("#RootSelector").searchInputId("#SearchInput").roots(roots).allowedExtensions(".prefab.json").enableRootSelector(true).enableSearch(true).enableDirectoryNav(true).maxResults(50).build();
        final String savedSearchQuery = builderState.getPrefabListSearchQuery();
        final Path initialRoot = roots.get(0).path();
        this.browser = new ServerFileBrowser(config, initialRoot, null);
        if (savedSearchQuery != null && !savedSearchQuery.isEmpty()) {
            this.browser.setSearchQuery(savedSearchQuery);
        }
    }
    
    @Nonnull
    private static List<FileBrowserConfig.RootEntry> buildRootEntries(@Nonnull final PrefabStore prefabStore) {
        final List<FileBrowserConfig.RootEntry> roots = new ObjectArrayList<FileBrowserConfig.RootEntry>();
        roots.add(new FileBrowserConfig.RootEntry("Assets", Paths.get("Assets", new String[0])));
        roots.add(new FileBrowserConfig.RootEntry("Server", prefabStore.getServerPrefabsPath()));
        return roots;
    }
    
    @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/PrefabListPage.ui");
        this.browser.buildRootSelector(commandBuilder, eventBuilder);
        this.browser.buildSearchInput(commandBuilder, eventBuilder);
        this.buildCurrentPath(commandBuilder);
        this.buildFileList(commandBuilder, eventBuilder);
    }
    
    @Override
    public void handleDataEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final FileBrowserEventData data) {
        if (data.getRoot() != null) {
            this.inAssetsRoot = "Assets".equals(data.getRoot());
            this.assetsCurrentDir = Paths.get("", new String[0]);
            this.browser.handleEvent(data);
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.buildCurrentPath(commandBuilder);
            this.buildFileList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        if (data.getSearchQuery() != null) {
            this.browser.handleEvent(data);
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.buildCurrentPath(commandBuilder);
            this.buildFileList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        final String selectedPath = (data.getSearchResult() != null) ? data.getSearchResult() : data.getFile();
        if (selectedPath != null) {
            if (this.inAssetsRoot) {
                this.handleAssetsNavigation(ref, store, selectedPath, data.getSearchResult() != null);
            }
            else {
                this.handleRegularNavigation(ref, store, selectedPath, data.getSearchResult() != null);
            }
        }
    }
    
    private void handleAssetsNavigation(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final String selectedPath, final boolean isSearchResult) {
        if ("..".equals(selectedPath)) {
            if (!this.assetsCurrentDir.toString().isEmpty()) {
                final Path parent = this.assetsCurrentDir.getParent();
                this.assetsCurrentDir = ((parent != null) ? parent : Paths.get("", new String[0]));
                final UICommandBuilder commandBuilder = new UICommandBuilder();
                final UIEventBuilder eventBuilder = new UIEventBuilder();
                this.buildCurrentPath(commandBuilder);
                this.buildFileList(commandBuilder, eventBuilder);
                this.sendUpdate(commandBuilder, eventBuilder, false);
            }
            return;
        }
        String targetVirtualPath;
        if (isSearchResult) {
            targetVirtualPath = selectedPath;
        }
        else {
            targetVirtualPath = (this.assetsCurrentDir.toString().isEmpty() ? selectedPath : (this.assetsCurrentDir.toString().replace('\\', '/') + "/" + selectedPath));
        }
        final Path resolvedPath = this.assetProvider.resolveVirtualPath(targetVirtualPath);
        if (resolvedPath == null) {
            this.sendUpdate();
            return;
        }
        if (Files.isDirectory(resolvedPath, new LinkOption[0])) {
            this.assetsCurrentDir = Paths.get(targetVirtualPath, new String[0]);
            final UICommandBuilder commandBuilder2 = new UICommandBuilder();
            final UIEventBuilder eventBuilder2 = new UIEventBuilder();
            this.buildCurrentPath(commandBuilder2);
            this.buildFileList(commandBuilder2, eventBuilder2);
            this.sendUpdate(commandBuilder2, eventBuilder2, false);
        }
        else {
            this.handlePrefabSelection(ref, store, resolvedPath, targetVirtualPath);
        }
    }
    
    private void handleRegularNavigation(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final String selectedPath, final boolean isSearchResult) {
        if (this.browser.handleEvent(FileBrowserEventData.file(selectedPath))) {
            final UICommandBuilder commandBuilder = new UICommandBuilder();
            final UIEventBuilder eventBuilder = new UIEventBuilder();
            this.buildCurrentPath(commandBuilder);
            this.buildFileList(commandBuilder, eventBuilder);
            this.sendUpdate(commandBuilder, eventBuilder, false);
            return;
        }
        Path file;
        if (isSearchResult) {
            file = this.browser.resolveSecure(selectedPath);
        }
        else {
            file = this.browser.resolveFromCurrent(selectedPath);
        }
        if (file == null || Files.isDirectory(file, new LinkOption[0])) {
            this.sendUpdate();
            return;
        }
        this.handlePrefabSelection(ref, store, file, selectedPath);
    }
    
    private void handlePrefabSelection(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store, @Nonnull final Path file, @Nonnull final String displayPath) {
        final Player playerComponent = store.getComponent(ref, Player.getComponentType());
        assert playerComponent != null;
        if (playerComponent.getGameMode() != GameMode.Creative) {
            playerComponent.getPageManager().setPage(ref, store, Page.None);
            return;
        }
        final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
        assert playerRefComponent != null;
        playerComponent.getPageManager().setPage(ref, store, Page.None);
        final BlockSelection prefab = PrefabStore.get().getPrefab(file);
        BuilderToolsPlugin.addToQueue(playerComponent, playerRefComponent, (r, s, componentAccessor) -> s.load(displayPath, prefab, componentAccessor));
        PasteToolUtil.switchToPasteTool(playerComponent, playerRefComponent);
    }
    
    private void buildCurrentPath(@Nonnull final UICommandBuilder commandBuilder) {
        String displayPath;
        if (this.inAssetsRoot) {
            final String currentDirStr = this.assetsCurrentDir.toString().replace('\\', '/');
            if (currentDirStr.isEmpty()) {
                displayPath = "Assets";
            }
            else {
                final String[] parts = currentDirStr.split("/", 2);
                final String packName = parts[0];
                final String subPath = (parts.length > 1) ? ("/" + parts[1]) : "";
                if ("HytaleAssets".equals(packName)) {
                    displayPath = packName + subPath;
                }
                else {
                    displayPath = "Mods/" + packName + subPath;
                }
            }
        }
        else {
            final Path root = this.browser.getRoot();
            final String rootDisplay = this.getRootDisplayName(root);
            final String currentPath = this.browser.getCurrentDir().toString().replace('\\', '/');
            displayPath = (currentPath.isEmpty() ? rootDisplay : (rootDisplay + "/" + currentPath));
        }
        commandBuilder.set("#CurrentPath.Text", displayPath);
    }
    
    @Nonnull
    private String getRootDisplayName(@Nonnull final Path root) {
        final PrefabStore prefabStore = PrefabStore.get();
        final String rootStr = root.toString();
        if ("Assets".equals(rootStr)) {
            return "Assets";
        }
        if (rootStr.equals(prefabStore.getServerPrefabsPath().toString())) {
            return "Server";
        }
        if (rootStr.equals(prefabStore.getWorldGenPrefabsPath().toString())) {
            return "WorldGen";
        }
        return (root.getFileName() != null) ? root.getFileName().toString() : rootStr;
    }
    
    private void buildFileList(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        if (this.inAssetsRoot) {
            this.buildAssetsFileList(commandBuilder, eventBuilder);
        }
        else {
            this.browser.buildFileList(commandBuilder, eventBuilder);
        }
    }
    
    private void buildAssetsFileList(@Nonnull final UICommandBuilder commandBuilder, @Nonnull final UIEventBuilder eventBuilder) {
        commandBuilder.clear("#FileList");
        final List<FileListProvider.FileEntry> entries = this.assetProvider.getFiles(this.assetsCurrentDir, this.browser.getSearchQuery());
        int buttonIndex = 0;
        if (!this.assetsCurrentDir.toString().isEmpty() && this.browser.getSearchQuery().isEmpty()) {
            commandBuilder.append("#FileList", "Pages/BasicTextButton.ui");
            commandBuilder.set("#FileList[0].Text", "../");
            eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#FileList[0]", EventData.of("File", ".."));
            ++buttonIndex;
        }
        for (FileListProvider.FileEntry entry : entries) {
            final String displayText = entry.isDirectory() ? entry.displayName() : entry.displayName();
            commandBuilder.append("#FileList", "Pages/BasicTextButton.ui");
            commandBuilder.set("#FileList[" + buttonIndex + "].Text", displayText);
            if (!entry.isDirectory()) {
                commandBuilder.set("#FileList[" + buttonIndex + "].Style", Value.ref("Pages/BasicTextButton.ui", "SelectedLabelStyle"));
            }
            final String eventKey = (!this.browser.getSearchQuery().isEmpty() && !entry.isDirectory()) ? "SearchResult" : "File";
            eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#FileList[" + buttonIndex, EventData.of(eventKey, entry.name()));
            ++buttonIndex;
        }
    }
}
