import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { useApplicationStore } from '@finos/legend-application';
import { observer } from 'mobx-react-lite';
import { BlankPanelContent, Panel, PanelLoadingIndicator, TreeView, ChevronDownIcon, ChevronRightIcon, GenericTextFileIcon, FolderIcon, FolderOpenIcon, HomeIcon, SearchIcon, TimesIcon, CodeIcon, clsx, CopyIcon, compareLabelFn, } from '@finos/legend-art';
import { SHOWCASE_MANAGER_SEARCH_CATEGORY, SHOWCASE_MANAGER_VIEW, ShowcaseManagerState, } from '../stores/ShowcaseManagerState.js';
import { debounce, isNonNullable } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
import { CodeEditor } from '@finos/legend-lego/code-editor';
import React, { useEffect, useMemo, useRef } from 'react';
import { generateShowcasePath } from '../__lib__/LegendStudioNavigation.js';
const ShowcasesExplorerTreeNodeContainer = observer((props) => {
    const { node, level, innerProps } = props;
    const { toggleExpandNode, showcaseManagerState } = innerProps;
    const applicationStore = useApplicationStore();
    const expandIcon = !node.metadata ? (node.isOpen ? (_jsx(ChevronDownIcon, {})) : (_jsx(ChevronRightIcon, {}))) : (_jsx("div", {}));
    const nodeIcon = !node.metadata ? (node.isOpen ? (_jsx(FolderOpenIcon, {})) : (_jsx(FolderIcon, {}))) : (_jsx(GenericTextFileIcon, {}));
    const onNodeClick = () => {
        if (!node.metadata) {
            toggleExpandNode(node);
        }
        else {
            flowResult(showcaseManagerState.openShowcase(node.metadata)).catch(applicationStore.alertUnhandledError);
        }
    };
    return (_jsxs("div", { className: "tree-view__node__container showcase-manager__explorer__node__container", style: {
            paddingLeft: `${(level - 1) * 1.4}rem`,
            display: 'flex',
        }, onClick: onNodeClick, children: [_jsx("div", { className: "showcase-manager__explorer__node__expand-icon", children: expandIcon }), _jsx("div", { className: "showcase-manager__explorer__node__type-icon", children: nodeIcon }), _jsx("div", { className: "tree-view__node__label showcase-manager__explorer__node__label", title: node.metadata
                    ? `${node.metadata.description
                        ? `${node.metadata.description}\n\n`
                        : ''}Click to open showcase`
                    : undefined, children: node.label })] }));
});
const ShowcaseManagerExplorer = observer((props) => {
    const { showcaseManagerState } = props;
    const treeData = showcaseManagerState.explorerTreeData;
    const getChildNodes = (node) => {
        if (treeData) {
            return node.childrenIds
                .map((id) => treeData.nodes.get(id))
                .filter(isNonNullable)
                .sort(compareLabelFn);
        }
        return [];
    };
    const toggleExpandNode = (node) => {
        if (treeData) {
            node.isOpen = !node.isOpen;
            showcaseManagerState.setExplorerTreeData({ ...treeData });
        }
    };
    return (_jsxs("div", { className: "showcase-manager__view", children: [_jsxs("div", { className: "showcase-manager__view__header", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumbs", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumb", children: [_jsx("div", { className: "showcase-manager__view__breadcrumb__icon", children: _jsx(HomeIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: "Showcases" })] }), _jsx("div", { className: "showcase-manager__view__breadcrumb__arrow", children: _jsx(ChevronRightIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb", children: _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: "Explorer" }) })] }), _jsx("button", { className: "showcase-manager__view__search-action", tabIndex: -1, title: "Search", onClick: () => {
                            showcaseManagerState.closeShowcase();
                            showcaseManagerState.setCurrentView(SHOWCASE_MANAGER_VIEW.SEARCH);
                        }, children: _jsx(SearchIcon, {}) })] }), _jsx("div", { className: "showcase-manager__view__content", children: _jsx("div", { className: "showcase-manager__explorer", children: showcaseManagerState.explorerTreeData && (_jsx(TreeView, { components: {
                            TreeNodeContainer: ShowcasesExplorerTreeNodeContainer,
                        }, treeData: showcaseManagerState.explorerTreeData, getChildNodes: getChildNodes, innerProps: {
                            toggleExpandNode,
                            showcaseManagerState,
                        } })) }) })] }));
});
const renderPreviewLine = (line, text, result) => {
    const lineMatches = result.match.matches
        .filter((match) => match.line === line)
        .sort((a, b) => a.startColumn - b.startColumn);
    const chunks = [];
    let currentIdx = 0;
    lineMatches.forEach((match, idx) => {
        if (currentIdx < match.startColumn - 1) {
            chunks.push(text.substring(currentIdx, match.startColumn - 1));
        }
        chunks.push(_jsx("span", { className: "showcase-manager__search__code-result__content__line__text--highlighted", children: text.substring(match.startColumn - 1, match.endColumn - 1) }));
        currentIdx = match.endColumn - 1;
    });
    if (currentIdx < text.length) {
        chunks.push(text.substring(currentIdx, text.length));
    }
    return (_jsx(_Fragment, { children: chunks.map((chunk, idx) => (
        // eslint-disable-next-line react/no-array-index-key
        _jsx(React.Fragment, { children: chunk }, idx))) }));
};
const ShowcaseManagerCodeSearchResult = observer((props) => {
    const { showcaseManagerState, result } = props;
    const applicationStore = useApplicationStore();
    return (_jsxs("div", { className: "showcase-manager__search__code-result", children: [_jsxs("div", { className: "showcase-manager__search__code-result__header", title: `Showcase: ${result.showcase.title}\n\n${result.showcase.description ?? '(no description)'}\n\nClick to open showcase`, onClick: () => {
                    flowResult(showcaseManagerState.openShowcase(result.showcase)).catch(applicationStore.alertUnhandledError);
                }, children: [_jsx("div", { className: "showcase-manager__search__code-result__header__icon", children: _jsx(GenericTextFileIcon, {}) }), _jsx("div", { className: "showcase-manager__search__code-result__header__title", children: result.showcase.path })] }), _jsx("div", { className: "showcase-manager__search__code-result__content", children: result.match.preview.map((entry) => (_jsxs("div", { className: "showcase-manager__search__code-result__content__line", onClick: () => {
                        flowResult(showcaseManagerState.openShowcase(result.showcase, entry.line)).catch(applicationStore.alertUnhandledError);
                    }, children: [_jsx("div", { className: clsx('showcase-manager__search__code-result__content__line__gutter', {
                                'showcase-manager__search__code-result__content__line__gutter--highlighted': Boolean(result.match.matches.find((match) => match.line === entry.line)),
                            }), children: entry.line }), _jsx("div", { className: "showcase-manager__search__code-result__content__line__text", children: renderPreviewLine(entry.line, entry.text, result) })] }, entry.line))) })] }));
});
const ShowcaseManagerSearchPanel = observer((props) => {
    const { showcaseManagerState } = props;
    const applicationStore = useApplicationStore();
    const searchTextInpurRef = useRef(null);
    const debouncedSearch = useMemo(() => debounce(() => flowResult(showcaseManagerState.search()).catch(applicationStore.alertUnhandledError), 300), [applicationStore, showcaseManagerState]);
    const clearSearchText = () => {
        debouncedSearch.cancel();
        showcaseManagerState.resetSearch();
    };
    const onSearchTextChange = (event) => {
        const value = event.target.value;
        showcaseManagerState.setSearchText(value);
        debouncedSearch.cancel();
        if (!value) {
            showcaseManagerState.resetSearch();
        }
        else {
            debouncedSearch()?.catch(applicationStore.alertUnhandledError);
        }
    };
    const onSearchKeyDown = (event) => {
        if (event.code === 'Enter') {
            debouncedSearch.cancel();
            if (showcaseManagerState.searchText) {
                debouncedSearch()?.catch(applicationStore.alertUnhandledError);
            }
        }
        else if (event.code === 'Escape') {
            searchTextInpurRef.current?.select();
        }
    };
    useEffect(() => {
        searchTextInpurRef.current?.select();
        searchTextInpurRef.current?.focus();
    }, []);
    return (_jsxs("div", { className: "showcase-manager__view", children: [_jsxs("div", { className: "showcase-manager__view__header", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumbs", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumb", onClick: () => {
                                    showcaseManagerState.closeShowcase();
                                    showcaseManagerState.setCurrentView(SHOWCASE_MANAGER_VIEW.EXPLORER);
                                }, children: [_jsx("div", { className: "showcase-manager__view__breadcrumb__icon", children: _jsx(HomeIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: "Showcases" })] }), _jsx("div", { className: "showcase-manager__view__breadcrumb__arrow", children: _jsx(ChevronRightIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb", children: _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: "Search" }) })] }), _jsx("button", { className: "showcase-manager__view__search-action", tabIndex: -1, title: "Search", onClick: () => {
                            // since we're already on the search tab, clicking this will just focus the search input
                            searchTextInpurRef.current?.select();
                        }, children: _jsx(SearchIcon, {}) })] }), _jsxs("div", { className: "showcase-manager__view__content", children: [_jsxs("div", { className: "showcase-manager__search__header", children: [_jsx("input", { ref: searchTextInpurRef, className: "showcase-manager__search__input input--dark", spellCheck: false, placeholder: "Search for showcase, code, etc.", value: showcaseManagerState.searchText, onChange: onSearchTextChange, onKeyDown: onSearchKeyDown }), !showcaseManagerState.searchText ? (_jsx("div", { className: "showcase-manager__search__input__search__icon", children: _jsx(SearchIcon, {}) })) : (_jsx("button", { className: "showcase-manager__search__input__clear-btn", tabIndex: -1, onClick: clearSearchText, title: "Clear", children: _jsx(TimesIcon, {}) }))] }), _jsxs("div", { className: "showcase-manager__search__results", children: [_jsxs("div", { className: "showcase-manager__search__results__categories", children: [_jsxs("div", { className: clsx('showcase-manager__search__results__category', {
                                            'showcase-manager__search__results__category--active': showcaseManagerState.currentSearchCaterogy ===
                                                SHOWCASE_MANAGER_SEARCH_CATEGORY.SHOWCASE,
                                        }), onClick: () => showcaseManagerState.setCurrentSearchCategory(SHOWCASE_MANAGER_SEARCH_CATEGORY.SHOWCASE), title: "Click to select category", children: [_jsxs("div", { className: "showcase-manager__search__results__category__content", children: [_jsx("div", { className: "showcase-manager__search__results__category__icon", children: _jsx(GenericTextFileIcon, {}) }), _jsx("div", { className: "showcase-manager__search__results__category__label", children: "Showcases" })] }), _jsx("div", { className: "showcase-manager__search__results__category__counter", children: showcaseManagerState.showcaseSearchResults?.length ?? 0 })] }), _jsxs("div", { className: clsx('showcase-manager__search__results__category', {
                                            'showcase-manager__search__results__category--active': showcaseManagerState.currentSearchCaterogy ===
                                                SHOWCASE_MANAGER_SEARCH_CATEGORY.CODE,
                                        }), onClick: () => showcaseManagerState.setCurrentSearchCategory(SHOWCASE_MANAGER_SEARCH_CATEGORY.CODE), title: "Click to select category", children: [_jsxs("div", { className: "showcase-manager__search__results__category__content", children: [_jsx("div", { className: "showcase-manager__search__results__category__icon", children: _jsx(CodeIcon, {}) }), _jsx("div", { className: "showcase-manager__search__results__category__label", children: "Code" })] }), _jsx("div", { className: "showcase-manager__search__results__category__counter", children: showcaseManagerState.textSearchResults?.length ?? 0 })] })] }), _jsxs("div", { className: "showcase-manager__search__results__list", children: [showcaseManagerState.currentSearchCaterogy ===
                                        SHOWCASE_MANAGER_SEARCH_CATEGORY.SHOWCASE && (_jsxs(_Fragment, { children: [!showcaseManagerState.showcaseSearchResults?.length && (_jsx(BlankPanelContent, { children: "No results" })), showcaseManagerState.showcaseSearchResults?.map((showcase) => (_jsxs("div", { className: "showcase-manager__search__showcase-result", title: `Showcase: ${showcase.title}\n\n${showcase.description ?? '(no description)'}\n\nClick to open showcase`, onClick: () => {
                                                    flowResult(showcaseManagerState.openShowcase(showcase)).catch(applicationStore.alertUnhandledError);
                                                }, children: [_jsx("div", { className: "showcase-manager__search__showcase-result__title", children: showcase.title }), _jsx("div", { className: "showcase-manager__search__showcase-result__description", children: showcase.description ?? '(no description)' })] }, showcase.uuid)))] })), showcaseManagerState.currentSearchCaterogy ===
                                        SHOWCASE_MANAGER_SEARCH_CATEGORY.CODE && (_jsxs(_Fragment, { children: [!showcaseManagerState.textSearchResults?.length && (_jsx(BlankPanelContent, { children: "No results" })), showcaseManagerState.textSearchResults?.map((result) => (_jsx(ShowcaseManagerCodeSearchResult, { showcaseManagerState: showcaseManagerState, result: result }, result.showcase.uuid)))] }))] })] })] })] }));
});
const ShowcaseViewer = observer((props) => {
    const { showcaseManagerState, showcase } = props;
    const prettyPath = showcase.path.replaceAll(/\s*\/\s*/g, ' / ');
    const launchShowcase = () => {
        const applicationStore = showcaseManagerState.applicationStore;
        applicationStore.navigationService.navigator.visitAddress(applicationStore.navigationService.navigator.generateAddress(generateShowcasePath(showcase.path)));
    };
    const handleCopy = showcaseManagerState.applicationStore.guardUnhandledError(() => showcaseManagerState.applicationStore.clipboardService.copyTextToClipboard(showcase.code, {
        notifySuccessMessage: 'Showcase grammar copied to clipboard',
    }));
    return (_jsxs("div", { className: "showcase-manager__view", children: [_jsxs("div", { className: "showcase-manager__view__header", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumbs", children: [_jsxs("div", { className: "showcase-manager__view__breadcrumb", onClick: () => {
                                    showcaseManagerState.closeShowcase();
                                    showcaseManagerState.setCurrentView(SHOWCASE_MANAGER_VIEW.EXPLORER);
                                }, children: [_jsx("div", { className: "showcase-manager__view__breadcrumb__icon", children: _jsx(HomeIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: "Showcases" })] }), _jsx("div", { className: "showcase-manager__view__breadcrumb__arrow", children: _jsx(ChevronRightIcon, {}) }), _jsxs("div", { className: "showcase-manager__view__breadcrumb", children: [_jsx("div", { className: "showcase-manager__view__breadcrumb__icon", children: _jsx(GenericTextFileIcon, {}) }), _jsx("div", { className: "showcase-manager__view__breadcrumb__text", children: showcase.title })] })] }), _jsx("button", { className: "showcase-manager__view__search-action", tabIndex: -1, title: "Search", onClick: () => {
                            showcaseManagerState.closeShowcase();
                            showcaseManagerState.setCurrentView(SHOWCASE_MANAGER_VIEW.SEARCH);
                        }, children: _jsx(SearchIcon, {}) })] }), _jsxs("div", { className: "showcase-manager__view__content showcase-manager__viewer__content", children: [_jsxs("div", { className: "showcase-manager__viewer__title", children: [_jsx("div", { className: "showcase-manager__viewer__title__label", children: showcase.title }), _jsx("div", { className: "showcase-manager__viewer__title__action", children: _jsx("div", { className: "btn__dropdown-combo btn__dropdown-combo--primary showcase-manager__viewer__title__action-btn", children: _jsx("button", { className: "btn__dropdown-combo__label", onClick: launchShowcase, title: "Open Showcase Project", tabIndex: -1, children: _jsx("div", { className: "btn__dropdown-combo__label__title", children: "Launch" }) }) }) }), _jsx("div", { className: "showcase-manager__viewer__title__action", children: _jsx("div", { onClick: handleCopy, className: "showcase-manager__viewer__title__action-icon", children: _jsx(CopyIcon, {}) }) })] }), _jsx("div", { className: "showcase-manager__viewer__path", children: prettyPath }), _jsx("div", { className: "showcase-manager__viewer__code", children: _jsx(CodeEditor, { language: CODE_EDITOR_LANGUAGE.PURE, inputValue: showcase.code, isReadOnly: true, lineToScroll: showcaseManagerState.showcaseLineToScroll }) })] })] }));
});
const ShowcaseManagerContent = observer((props) => {
    const { showcaseManagerState } = props;
    const currentShowcase = showcaseManagerState.currentShowcase;
    const currentView = showcaseManagerState.currentView;
    return (_jsxs("div", { className: "showcase-manager", children: [currentShowcase && (_jsx(ShowcaseViewer, { showcaseManagerState: showcaseManagerState, showcase: currentShowcase })), !currentShowcase && (_jsxs(_Fragment, { children: [currentView === SHOWCASE_MANAGER_VIEW.EXPLORER && (_jsx(ShowcaseManagerExplorer, { showcaseManagerState: showcaseManagerState })), currentView === SHOWCASE_MANAGER_VIEW.SEARCH && (_jsx(ShowcaseManagerSearchPanel, { showcaseManagerState: showcaseManagerState }))] }))] }));
});
export const ShowcaseManager = observer(() => {
    const applicationStore = useApplicationStore();
    const showcaseManagerState = ShowcaseManagerState.retrieveNullableState(applicationStore);
    if (!showcaseManagerState) {
        return null;
    }
    return (_jsxs(Panel, { children: [_jsx(PanelLoadingIndicator, { isLoading: showcaseManagerState.initState.isInProgress }), showcaseManagerState.initState.isInProgress && (_jsx(BlankPanelContent, { children: "Initializing..." })), showcaseManagerState.initState.hasFailed && (_jsx(BlankPanelContent, { children: "Failed to initialize" })), showcaseManagerState.initState.hasSucceeded && (_jsx(ShowcaseManagerContent, { showcaseManagerState: showcaseManagerState }))] }));
});
//# sourceMappingURL=ShowcaseManager.js.map