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 { CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
import { CodeEditor } from '@finos/legend-lego/code-editor';
import { Dialog, Modal, ModalTitle, clsx, SearchIcon, TimesIcon, ControlledDropdownMenu, MenuContent, MenuContentItem, PanelLoadingIndicator, ModalHeader, ModalBody, ModalFooter, ModalFooterButton, UserIcon, LastModifiedIcon, MoreVerticalIcon, ThinChevronRightIcon, InfoCircleIcon, CustomSelectorInput, CubesLoadingIndicator, CubesLoadingIndicatorIcon, } from '@finos/legend-art';
import { debounce, formatDistanceToNow, guaranteeNonNullable, isNonNullable, quantifyList, } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { observer } from 'mobx-react-lite';
import { useRef, useState, useMemo, useEffect } from 'react';
import { QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT, SORT_BY_OPTIONS, } from '../stores/QueryLoaderState.js';
const QueryPreviewViewer = observer((props) => {
    const { queryLoaderState } = props;
    const applicationStore = queryLoaderState.applicationStore;
    const close = () => {
        queryLoaderState.setShowPreviewViewer(false);
    };
    return (_jsx(Dialog, { open: queryLoaderState.showPreviewViewer, onClose: close, classes: {
            root: 'editor-modal__root-container',
            container: 'editor-modal__container',
            paper: 'editor-modal__content',
        }, children: _jsxs(Modal, { className: "editor-modal", darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, children: [_jsx(ModalHeader, { title: guaranteeNonNullable(queryLoaderState.queryPreviewContent).name }), _jsx(ModalBody, { children: _jsx(CodeEditor, { inputValue: guaranteeNonNullable(queryLoaderState.queryPreviewContent)
                            .content, isReadOnly: true, language: CODE_EDITOR_LANGUAGE.PURE }) }), _jsx(ModalFooter, { children: _jsx(ModalFooterButton, { onClick: close, text: "Close", type: "secondary" }) })] }) }));
});
export const QueryLoader = observer((props) => {
    const { queryLoaderState, loadActionLabel } = props;
    const applicationStore = useApplicationStore();
    const searchInputRef = useRef(null);
    const searchResults = queryLoaderState.queries;
    // curated template queries
    const curatedTemplateQueries = [
        ...queryLoaderState.curatedTemplateQuerySpecifications
            .map((s) => queryLoaderState.queryBuilderState
            ? s.getCuratedTemplateQueries(queryLoaderState.queryBuilderState)
            : [])
            .flat(),
    ].sort((a, b) => a.title.localeCompare(b.title));
    const loadCuratedTemplateQuery = queryLoaderState.curatedTemplateQuerySpecifications
        // already using an arrow function suggested by @typescript-eslint/unbound-method
        // eslint-disable-next-line
        .map((s) => () => s.loadCuratedTemplateQuery)
        .filter(isNonNullable)[0];
    // search filters
    const sortOptions = Object.values(SORT_BY_OPTIONS).map((op) => ({
        label: op,
        value: op,
    }));
    const [isMineOnly, setIsMineOnly] = useState(false);
    const [showQueryNameEditInput, setShowQueryNameEditInput] = useState();
    // search text
    const debouncedLoadQueries = useMemo(() => debounce((input) => {
        flowResult(queryLoaderState.searchQueries(input)).catch(applicationStore.alertUnhandledError);
    }, 500), [applicationStore.alertUnhandledError, queryLoaderState]);
    const onSearchTextChange = (event) => {
        if (event.target.value !== queryLoaderState.searchText) {
            queryLoaderState.setSearchText(event.target.value);
            debouncedLoadQueries.cancel();
            debouncedLoadQueries(event.target.value);
        }
    };
    const clearSearchResults = () => {
        queryLoaderState.setSearchText('');
        debouncedLoadQueries.cancel();
        debouncedLoadQueries('');
    };
    const toggleShowCurrentUserQueriesOnly = () => {
        queryLoaderState.setShowCurrentUserQueriesOnly(!queryLoaderState.showCurrentUserQueriesOnly);
        setIsMineOnly(!isMineOnly);
        debouncedLoadQueries.cancel();
        debouncedLoadQueries(queryLoaderState.searchText);
    };
    const applySort = (option) => {
        queryLoaderState.setSortBy(option.value);
        debouncedLoadQueries.cancel();
        debouncedLoadQueries(queryLoaderState.searchText);
    };
    const toggleExtraFilters = (key) => {
        queryLoaderState.extraFilters.set(key, !queryLoaderState.extraFilters.get(key));
        debouncedLoadQueries.cancel();
        debouncedLoadQueries(queryLoaderState.searchText);
    };
    const toggleCuratedTemplate = () => {
        Array.from(queryLoaderState.extraFilters).forEach(([key, value]) => queryLoaderState.extraFilters.set(key, false));
        queryLoaderState.setShowCurrentUserQueriesOnly(false);
        setIsMineOnly(false);
        queryLoaderState.extraQueryFilterOptionsRelatedToTemplateQuery.forEach((op) => queryLoaderState.extraFilters.set(op, !queryLoaderState.isCuratedTemplateToggled));
        queryLoaderState.showingDefaultQueries =
            queryLoaderState.isCuratedTemplateToggled;
        queryLoaderState.setIsCuratedTemplateToggled(!queryLoaderState.isCuratedTemplateToggled);
    };
    useEffect(() => {
        flowResult(queryLoaderState.searchQueries('')).catch(applicationStore.alertUnhandledError);
    }, [applicationStore, queryLoaderState]);
    useEffect(() => {
        searchInputRef.current?.focus();
    }, [queryLoaderState]);
    // query rename
    const queryRenameInputRef = useRef(null);
    useEffect(() => {
        queryRenameInputRef.current?.focus();
        queryRenameInputRef.current?.select();
    }, [showQueryNameEditInput]);
    const [queryNameInputValue, setQueryNameInputValue] = useState('');
    const showEditQueryNameInput = (value, idx) => () => {
        setQueryNameInputValue(value);
        setShowQueryNameEditInput(idx);
    };
    const hideEditQueryNameInput = () => {
        setShowQueryNameEditInput(undefined);
        setQueryNameInputValue('');
    };
    const changeQueryNameInputValue = (event) => setQueryNameInputValue(event.target.value);
    const renameQuery = (query) => () => {
        if (!queryLoaderState.isReadOnly) {
            flowResult(queryLoaderState.renameQuery(query.id, queryNameInputValue))
                .catch(applicationStore.alertUnhandledError)
                .finally(() => hideEditQueryNameInput());
        }
    };
    // other actions
    const deleteQuery = (query) => () => {
        if (!queryLoaderState.isReadOnly) {
            flowResult(queryLoaderState.deleteQuery(query.id)).catch(applicationStore.alertUnhandledError);
        }
    };
    const showPreview = (queryId, template) => {
        flowResult(queryLoaderState.getPreviewQueryContent(queryId, template)).catch(applicationStore.alertUnhandledError);
        queryLoaderState.setShowPreviewViewer(true);
    };
    return (_jsxs("div", { className: "query-loader", children: [_jsxs("div", { className: "query-loader__header", children: [_jsx("div", { className: "query-loader__search", children: _jsxs("div", { className: "query-loader__search__input__container", children: [_jsx("input", { ref: searchInputRef, className: clsx('query-loader__search__input input--dark', {
                                        'query-loader__search__input--searching': queryLoaderState.searchText,
                                    }), onChange: onSearchTextChange, value: queryLoaderState.searchText, placeholder: "Search for queries by name or ID" }), !queryLoaderState.searchText ? (_jsx("div", { className: "query-loader__search__input__search__icon", children: _jsx(SearchIcon, {}) })) : (_jsx(_Fragment, { children: _jsx("button", { className: "query-loader__search__input__clear-btn", tabIndex: -1, onClick: clearSearchResults, title: "Clear", children: _jsx(TimesIcon, {}) }) }))] }) }), _jsx("div", { className: "query-loader__filter", children: _jsxs("div", { className: "query-loader__filter__toggler", children: [_jsx("button", { className: clsx('query-loader__filter__toggler__btn', {
                                        'query-loader__filter__toggler__btn--toggled': isMineOnly,
                                    }), onClick: toggleShowCurrentUserQueriesOnly, disabled: queryLoaderState.isCuratedTemplateToggled, title: queryLoaderState.isCuratedTemplateToggled
                                        ? 'current fitler is disabled when `Curated Template Query` is on'
                                        : 'click to add filter', tabIndex: -1, children: "Mine Only" }), queryLoaderState.extraFilterOptions.length > 0 && (_jsx("div", { className: "query-loader__filter__extra__filters", children: Array.from(queryLoaderState.extraFilters.entries()).map(([key, value]) => (_jsx("button", { className: clsx('query-loader__filter__toggler__btn', {
                                            'query-loader__filter__toggler__btn--toggled': value,
                                        }), disabled: queryLoaderState.isCuratedTemplateToggled, title: queryLoaderState.isCuratedTemplateToggled
                                            ? 'current fitler is disabled when `Curated Template Query` is on'
                                            : 'click to add filter', onClick: () => toggleExtraFilters(key), tabIndex: -1, children: key }, key))) })), queryLoaderState.extraQueryFilterOptionsRelatedToTemplateQuery
                                    .length > 0 && (_jsx("div", { className: "query-loader__filter__extra__filters", children: _jsx("button", { className: clsx('query-loader__filter__toggler__btn', {
                                            'query-loader__filter__toggler__btn--toggled': queryLoaderState.isCuratedTemplateToggled,
                                        }), onClick: toggleCuratedTemplate, tabIndex: -1, children: "Curated Template Query" }) }))] }) })] }), _jsxs("div", { className: "query-loader__content", children: [_jsx(PanelLoadingIndicator, { isLoading: queryLoaderState.searchQueriesState.isInProgress ||
                            queryLoaderState.renameQueryState.isInProgress ||
                            queryLoaderState.deleteQueryState.isInProgress ||
                            queryLoaderState.previewQueryState.isInProgress }), _jsxs("div", { className: "query-loader__results", children: [queryLoaderState.searchQueriesState.hasCompleted && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "query-loader__results__summary", children: [queryLoaderState.showingDefaultQueries ? ((queryLoaderState.generateDefaultQueriesSummaryText?.(searchResults) ?? 'Refine your search to get better matches')) : !queryLoaderState.isCuratedTemplateToggled ? (searchResults.length >=
                                                QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (_jsxs(_Fragment, { children: [`Found ${QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`, ' ', _jsx(InfoCircleIcon, { title: "Some queries are not listed, refine your search to get better matches", className: "query-loader__results__summary__info" })] })) : (`Found ${quantifyList(searchResults, 'match', 'matches')}`)) : curatedTemplateQueries.length >=
                                                QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (_jsxs(_Fragment, { children: [`Found ${QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`, ' ', _jsx(InfoCircleIcon, { title: "Some queries are not listed, refine your search to get better matches", className: "query-loader__results__summary__info" })] })) : (`Found ${quantifyList(curatedTemplateQueries, 'match', 'matches')}`), queryLoaderState.canPerformAdvancedSearch(queryLoaderState.searchText) &&
                                                !queryLoaderState.isCuratedTemplateToggled && (_jsxs("div", { className: "query-loader__results__sort-by", children: [_jsx("div", { className: "query-loader__results__sort-by__name", children: "Sort By" }), _jsx(CustomSelectorInput, { className: "query-loader__results__sort-by__selector", options: sortOptions, onChange: (option) => {
                                                            applySort(option);
                                                        }, value: {
                                                            label: queryLoaderState.sortBy,
                                                            value: queryLoaderState.sortBy,
                                                        }, darkMode: !applicationStore.layoutService
                                                            .TEMPORARY__isLightColorThemeEnabled })] }))] }), !queryLoaderState.isCuratedTemplateToggled &&
                                        searchResults
                                            .slice(0, QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
                                            .map((query, idx) => (_jsxs("div", { className: "query-loader__result", title: `Click to ${loadActionLabel}...`, onClick: () => queryLoaderState.loadQuery(query), children: [_jsxs("div", { className: "query-loader__result__content", children: [showQueryNameEditInput === idx ? (_jsx("div", { className: "query-loader__result__title__editor", children: _jsx("input", { className: "query-loader__result__title__editor__input input--dark", spellCheck: false, ref: queryRenameInputRef, value: queryNameInputValue, onChange: changeQueryNameInputValue, onKeyDown: (event) => {
                                                                    if (event.code === 'Enter') {
                                                                        event.stopPropagation();
                                                                        renameQuery(query)();
                                                                    }
                                                                    else if (event.code === 'Escape') {
                                                                        event.stopPropagation();
                                                                        hideEditQueryNameInput();
                                                                    }
                                                                }, onBlur: () => hideEditQueryNameInput(), 
                                                                // avoid clicking on the input causing the call to load query
                                                                onClick: (event) => event.stopPropagation() }) })) : (_jsx("div", { className: "query-loader__result__title", title: query.name, children: query.name })), _jsxs("div", { className: "query-loader__result__description", children: [_jsx("div", { className: "query-loader__result__description__date__icon", children: _jsx(LastModifiedIcon, {}) }), _jsx("div", { className: "query-loader__result__description__date", children: query.lastUpdatedAt
                                                                        ? formatDistanceToNow(new Date(query.lastUpdatedAt), {
                                                                            includeSeconds: true,
                                                                            addSuffix: true,
                                                                        })
                                                                        : '(unknown)' }), _jsx("div", { className: clsx('query-loader__result__description__author__icon', {
                                                                        'query-loader__result__description__author__icon--owner': query.isCurrentUserQuery,
                                                                    }), children: _jsx(UserIcon, {}) }), _jsx("div", { className: "query-loader__result__description__author__name", children: query.isCurrentUserQuery ? (_jsx("div", { title: query.owner, className: "query-loader__result__description__owner", children: "Me" })) : (query.owner) })] })] }), _jsx(ControlledDropdownMenu, { className: "query-loader__result__actions-menu", title: "More Actions...", content: _jsxs(MenuContent, { children: [_jsx(MenuContentItem, { onClick: () => showPreview(query.id), children: "Show Query Preview" }), !queryLoaderState.isReadOnly && (_jsx(MenuContentItem, { disabled: !query.isCurrentUserQuery, onClick: deleteQuery(query), children: "Delete" })), !queryLoaderState.isReadOnly && (_jsx(MenuContentItem, { disabled: !query.isCurrentUserQuery, onClick: showEditQueryNameInput(query.name, idx), children: "Rename" }))] }), menuProps: {
                                                        anchorOrigin: {
                                                            vertical: 'bottom',
                                                            horizontal: 'left',
                                                        },
                                                        transformOrigin: {
                                                            vertical: 'top',
                                                            horizontal: 'left',
                                                        },
                                                        elevation: 7,
                                                    }, children: _jsx(MoreVerticalIcon, {}) }), _jsx("div", { className: "query-loader__result__arrow", children: _jsx(ThinChevronRightIcon, {}) })] }, query.id))), queryLoaderState.queryBuilderState &&
                                        queryLoaderState.isCuratedTemplateToggled &&
                                        loadCuratedTemplateQuery &&
                                        curatedTemplateQueries
                                            .slice(0, QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
                                            .map((templateQuery, idx) => (_jsxs("div", { className: "query-loader__result", title: `Click to ${loadActionLabel}...`, onClick: () => {
                                                flowResult(loadCuratedTemplateQuery()(templateQuery, guaranteeNonNullable(queryLoaderState.queryBuilderState)));
                                                queryLoaderState.setQueryLoaderDialogOpen(false);
                                            }, children: [_jsxs("div", { className: "query-loader__result__content", children: [_jsx("div", { className: "query-loader__result__title", title: templateQuery.title, children: templateQuery.title }), _jsx("div", { className: "query-loader__result__description", children: templateQuery.description })] }), _jsx(ControlledDropdownMenu, { className: "query-loader__result__actions-menu", title: "More Actions...", content: _jsx(MenuContent, { children: _jsx(MenuContentItem, { onClick: () => showPreview(undefined, {
                                                                queryContent: templateQuery.query,
                                                                queryName: templateQuery.title,
                                                            }), children: "Show Query Preview" }) }), menuProps: {
                                                        anchorOrigin: {
                                                            vertical: 'bottom',
                                                            horizontal: 'left',
                                                        },
                                                        transformOrigin: {
                                                            vertical: 'top',
                                                            horizontal: 'left',
                                                        },
                                                        elevation: 7,
                                                    }, children: _jsx(MoreVerticalIcon, {}) }), _jsx("div", { className: "query-loader__result__arrow", children: _jsx(ThinChevronRightIcon, {}) })] }, templateQuery.title)))] })), !queryLoaderState.searchQueriesState.hasCompleted && (_jsx(CubesLoadingIndicator, { isLoading: !queryLoaderState.searchQueriesState.hasCompleted, children: _jsx(CubesLoadingIndicatorIcon, {}) }))] }), queryLoaderState.showPreviewViewer &&
                        queryLoaderState.queryPreviewContent && (_jsx(QueryPreviewViewer, { queryLoaderState: queryLoaderState }))] })] }));
});
export const QueryLoaderDialog = observer((props) => {
    const { queryLoaderState, title, loadActionLabel } = props;
    const applicationStore = queryLoaderState.applicationStore;
    const close = () => {
        queryLoaderState.setQueryLoaderDialogOpen(false);
        queryLoaderState.reset();
    };
    return (_jsx(Dialog, { open: queryLoaderState.isQueryLoaderDialogOpen, onClose: close, classes: {
            root: 'query-loader__dialog',
            container: 'query-loader__dialog__container',
        }, slotProps: {
            paper: {
                classes: { root: 'query-loader__dialog__body' },
            },
        }, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "modal query-loader__dialog__body__content", children: [_jsxs("div", { className: "modal query-loader__dialog__header", children: [_jsx(ModalTitle, { className: "query-loader__dialog__header__title", title: title }), _jsx("button", { className: "query-loader__dialog__header__close-btn", title: "Close", onClick: close, children: _jsx(TimesIcon, {}) })] }), _jsx("div", { className: "modal query-loader__dialog__content", children: _jsx(QueryLoader, { queryLoaderState: queryLoaderState, loadActionLabel: loadActionLabel ?? title.toLowerCase() }) })] }) }));
});
//# sourceMappingURL=QueryLoader.js.map