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 { useEffect, useRef, useState } from 'react';
import { observer } from 'mobx-react-lite';
import { FolderIcon, FolderOpenIcon, InfoCircleIcon, SubjectIcon, Tooltip, ViewHeadlineIcon, ChevronDownIcon, ChevronRightIcon, PURE_FunctionIcon, CompressIcon, TreeView, BlankPanelContent, MenuContentItem, ControlledDropdownMenu, MenuContent, CheckIcon, MenuContentItemIcon, MenuContentItemLabel, MoreVerticalIcon, DragPreviewLayer, useDragPreviewLayer, } from '@finos/legend-art';
import { getFunctionsExplorerTreeNodeChildren, QUERY_BUILDER_FUNCTION_DND_TYPE, generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo, } from '../../stores/explorer/QueryFunctionsExplorerState.js';
import { useDrag } from 'react-dnd';
import { getElementRootPackage, ROOT_PACKAGE_NAME, getMultiplicityDescription, CORE_PURE_PATH, PURE_DOC_TAG, } from '@finos/legend-graph';
import { QueryBuilderTelemetryHelper } from '../../__lib__/QueryBuilderTelemetryHelper.js';
import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
const isDependencyTreeNode = (node) => node.package !== undefined &&
    getElementRootPackage(node.package).name ===
        ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT;
const QueryBuilderFunctionInfoTooltip = (props) => {
    const { children, placement, functionInfo } = props;
    const documentation = functionInfo.taggedValues
        .filter((taggedValue) => taggedValue.tag.ownerReference.value.path ===
        CORE_PURE_PATH.PROFILE_DOC &&
        taggedValue.tag.value.value === PURE_DOC_TAG)
        .map((taggedValue) => taggedValue.value);
    const generateParameterCallString = () => {
        if (functionInfo.parameterInfoList.length &&
            functionInfo.parameterInfoList.length > 0) {
            return functionInfo.parameterInfoList
                .map((param) => `${param.name}: ${param.type}${getMultiplicityDescription(param.multiplicity)}`)
                .join('; ');
        }
        return '';
    };
    return (_jsx(Tooltip, { arrow: true, ...(placement !== undefined ? { placement } : {}), classes: {
            tooltip: 'query-builder__tooltip',
            arrow: 'query-builder__tooltip__arrow',
            tooltipPlacementRight: 'query-builder__tooltip--right',
        }, slotProps: {
            transition: {
                timeout: 0,
            },
        }, title: _jsxs("div", { className: "query-builder__tooltip__content", children: [_jsxs("div", { className: "query-builder__tooltip__item", children: [_jsx("div", { className: "query-builder__tooltip__item__label", children: "Function Name" }), _jsx("div", { className: "query-builder__tooltip__item__value", children: functionInfo.functionPath })] }), _jsxs("div", { className: "query-builder__tooltip__item", children: [_jsx("div", { className: "query-builder__tooltip__item__label", children: "Parameters" }), _jsx("div", { className: "query-builder__tooltip__item__value", children: generateParameterCallString() })] }), Boolean(documentation.length) && (_jsxs("div", { className: "query-builder__tooltip__item", children: [_jsx("div", { className: "query-builder__tooltip__item__label", children: "Documentation" }), _jsx("div", { className: "query-builder__tooltip__item__value", children: documentation.join('\n\n') })] })), _jsxs("div", { className: "query-builder__tooltip__item", children: [_jsx("div", { className: "query-builder__tooltip__item__label", children: "Return Type" }), _jsx("div", { className: "query-builder__tooltip__item__value", children: functionInfo.returnType })] })] }), children: _jsx("span", { children: children }) }));
};
const QueryBuilderFunctionsExplorerListEntry = observer((props) => {
    const { element } = props;
    const node = generateFunctionsExplorerTreeNodeDataFromFunctionAnalysisInfo(element);
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: QUERY_BUILDER_FUNCTION_DND_TYPE,
        item: { node: node },
    }), [node]);
    const ref = useRef(null);
    dragConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    return (_jsxs("div", { className: "query-builder__functions-explorer__function", ref: ref, children: [_jsxs("div", { className: "query-builder__functions-explorer__function__content", children: [_jsx("div", { className: "query-builder__functions-explorer__function__icon", children: _jsx("div", { className: "query-builder__functions-explorer__function-icon", children: _jsx(PURE_FunctionIcon, {}) }) }), _jsx("div", { className: "query-builder__functions-explorer__function__label", title: element.functionPrettyName, children: element.functionPrettyName })] }), _jsx("div", { className: "query-builder__functions-explorer__function__actions", children: _jsx(QueryBuilderFunctionInfoTooltip, { functionInfo: element, children: _jsx("div", { className: "query-builder__functions-explorer__function__action query-builder__functions-explorer__function__node__info", children: _jsx(InfoCircleIcon, {}) }) }) })] }));
});
const QueryBuilderFunctionsExplorerTreeNodeContainer = observer((props) => {
    const { node, level, stepPaddingInRem, onNodeSelect } = props;
    const name = node.functionAnalysisInfo
        ? node.functionAnalysisInfo.functionPrettyName.split(`${node.functionAnalysisInfo.packagePath}::`)[1]
        : (node.package?.name ?? '');
    const isExpandable = Boolean(node.childrenIds.length);
    const nodeExpandIcon = isExpandable ? (node.isOpen ? (_jsx(ChevronDownIcon, {})) : (_jsx(ChevronRightIcon, {}))) : (_jsx("div", {}));
    const iconPackageColor = isDependencyTreeNode(node)
        ? 'color--dependency'
        : '';
    const nodeTypeIcon = node.package ? (node.isOpen ? (_jsx(FolderOpenIcon, { className: iconPackageColor })) : (_jsx(FolderIcon, { className: iconPackageColor }))) : (_jsx(PURE_FunctionIcon, {}));
    const selectNode = () => {
        onNodeSelect?.(node);
    };
    const [, dragConnector, dragPreviewConnector] = useDrag(() => ({
        type: QUERY_BUILDER_FUNCTION_DND_TYPE,
        item: () => (node.functionAnalysisInfo ? { node } : {}),
    }), [node]);
    const ref = useRef(null);
    dragConnector(ref);
    useDragPreviewLayer(dragPreviewConnector);
    return (_jsx("div", { children: _jsx("div", { className: "tree-view__node__container query-builder__functions-explorer__tree__node__container", onClick: selectNode, ref: !isExpandable ? ref : undefined, style: {
                paddingLeft: `${(level - 1) * (stepPaddingInRem ?? 1) + 0.5}rem`,
                display: 'flex',
            }, children: _jsxs(_Fragment, { children: [_jsxs("div", { className: "tree-view__node__icon query-builder__functions-explorer__tree__node__icon", children: [_jsx("div", { className: "query-builder__functions-explorer__tree__expand-icon", children: nodeExpandIcon }), _jsx("div", { className: 'query-builder__functions-explorer__tree__type-icon', children: nodeTypeIcon })] }), _jsx("div", { className: "tree-view__node__label query-builder__functions-explorer__tree__node__label--with-action", title: name, children: name }), _jsx("div", { className: "query-builder__functions-explorer__tree__node__actions", children: node.functionAnalysisInfo && (_jsx(QueryBuilderFunctionInfoTooltip, { functionInfo: node.functionAnalysisInfo, children: _jsx("div", { className: "query-builder__functions-explorer__tree__node__action query-builder__functions-explorer__tree__node__info", children: _jsx(InfoCircleIcon, {}) }) })) })] }) }) }));
});
const QueryBuilderPackableElementExplorerTree = observer((props) => {
    const { queryBuilderState, rootPackageName, showDependencyFuncions } = props;
    const queryFunctionsState = queryBuilderState.functionsExplorerState;
    const treeData = queryFunctionsState.nonNullableTreeData;
    const onNodeSelect = (node) => queryFunctionsState.onTreeNodeSelect(queryBuilderState, node, treeData);
    const getChildNodes = (node) => getFunctionsExplorerTreeNodeChildren(queryBuilderState, node, treeData);
    const dependencyTreeData = queryFunctionsState.getTreeData(ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT);
    const onDependencyTreeSelect = (node) => {
        if (dependencyTreeData) {
            queryFunctionsState.onTreeNodeSelect(queryBuilderState, node, dependencyTreeData, ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT);
        }
    };
    const getDependencyTreeChildNodes = (node) => {
        if (dependencyTreeData) {
            return getFunctionsExplorerTreeNodeChildren(queryBuilderState, node, dependencyTreeData, ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT);
        }
        return [];
    };
    return (_jsxs(_Fragment, { children: [rootPackageName === ROOT_PACKAGE_NAME.MAIN && (_jsx(TreeView, { components: {
                    TreeNodeContainer: QueryBuilderFunctionsExplorerTreeNodeContainer,
                }, className: "query-builder__functions-explorer__tree__root", treeData: treeData, onNodeSelect: onNodeSelect, getChildNodes: getChildNodes, innerProps: {
                    queryBuilderState,
                } })), rootPackageName === ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT &&
                dependencyTreeData &&
                showDependencyFuncions && (_jsx(_Fragment, { children: _jsx(TreeView, { components: {
                        TreeNodeContainer: QueryBuilderFunctionsExplorerTreeNodeContainer,
                    }, className: "query-builder__functions-explorer__tree__root", treeData: dependencyTreeData, onNodeSelect: onDependencyTreeSelect, getChildNodes: getDependencyTreeChildNodes, innerProps: {
                        queryBuilderState,
                    } }) }))] }));
});
export const QueryBuilderFunctionsExplorerPanel = observer((props) => {
    const { queryBuilderState } = props;
    const queryFunctionsState = queryBuilderState.functionsExplorerState;
    const [viewAsTree, setViewAsTree] = useState(false);
    const [showDependencyFuncions, setShowDependencyFuncions] = useState(false);
    const toggleViewAsListOrAsTree = () => {
        setViewAsTree(!viewAsTree);
    };
    const collapseTree = () => {
        if (queryFunctionsState.treeData) {
            Array.from(queryFunctionsState.treeData.nodes.values()).forEach((node) => {
                node.isOpen = false;
            });
        }
        if (queryFunctionsState.dependencyTreeData) {
            Array.from(queryFunctionsState.dependencyTreeData.nodes.values()).forEach((node) => {
                node.isOpen = false;
            });
        }
        queryFunctionsState.refreshTree();
    };
    const toggleShowDependencyFunctions = () => {
        QueryBuilderTelemetryHelper.logEvent_TogglePanelFunctionExplorerDependencyView(queryBuilderState.applicationStore.telemetryService);
        setShowDependencyFuncions(!showDependencyFuncions);
    };
    useEffect(() => {
        queryFunctionsState.initializeTreeData();
    }, [queryFunctionsState]);
    useEffect(() => {
        QueryBuilderTelemetryHelper.logEvent_RenderPanelFunctionExplorer(queryBuilderState.applicationStore.telemetryService);
    }, [queryBuilderState.applicationStore]);
    return (_jsxs("div", { "data-testid": QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FUNCTIONS, className: "panel query-builder__functions-explorer", children: [_jsxs("div", { className: "panel__header", children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: "functions" }) }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action", onClick: collapseTree, tabIndex: -1, children: viewAsTree && _jsx(CompressIcon, { title: "Collapse Tree" }) }), _jsx("div", { className: "panel__header__action query-builder__functions-explorer__custom-icon", children: !viewAsTree ? (_jsx(SubjectIcon, { title: "View as Tree", onClick: toggleViewAsListOrAsTree })) : (_jsx(ViewHeadlineIcon, { title: "View as List", onClick: toggleViewAsListOrAsTree })) }), _jsx(ControlledDropdownMenu, { className: "panel__header__action", title: "Show Options Menu...", content: _jsx(MenuContent, { children: _jsxs(MenuContentItem, { onClick: toggleShowDependencyFunctions, children: [_jsx(MenuContentItemIcon, { children: showDependencyFuncions ? _jsx(CheckIcon, {}) : null }), _jsx(MenuContentItemLabel, { children: "Show functions from dependency projects" })] }) }), menuProps: {
                                    anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
                                    transformOrigin: { vertical: 'top', horizontal: 'left' },
                                    elevation: 7,
                                }, children: _jsx(MoreVerticalIcon, { className: "query-builder__icon__more-options" }) })] })] }), _jsxs("div", { className: "panel__content query-builder__functions-explorer__content", children: [_jsx(DragPreviewLayer, { labelGetter: (item) => item.node.functionAnalysisInfo?.functionPrettyName ?? '', types: [QUERY_BUILDER_FUNCTION_DND_TYPE] }), ((showDependencyFuncions &&
                        queryFunctionsState.dependencyFunctionExplorerStates.length ===
                            0) ||
                        !showDependencyFuncions) &&
                        queryFunctionsState.treeData?.rootIds.length === 0 && (_jsx(BlankPanelContent, { children: "No user-defined functions available" })), viewAsTree && (_jsxs(_Fragment, { children: [queryFunctionsState.treeData && (_jsx(QueryBuilderPackableElementExplorerTree, { queryBuilderState: queryBuilderState, rootPackageName: ROOT_PACKAGE_NAME.MAIN, showDependencyFuncions: showDependencyFuncions })), showDependencyFuncions &&
                                queryFunctionsState.dependencyFunctionExplorerStates.length !==
                                    0 && (_jsx(QueryBuilderPackableElementExplorerTree, { queryBuilderState: queryBuilderState, rootPackageName: ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT, showDependencyFuncions: showDependencyFuncions }))] })), !viewAsTree && (_jsxs(_Fragment, { children: [queryFunctionsState.functionExplorerStates.map((funcExplorerState) => (_jsx(QueryBuilderFunctionsExplorerListEntry, { element: funcExplorerState.functionAnalysisInfo }, funcExplorerState.uuid))), showDependencyFuncions &&
                                queryFunctionsState.dependencyFunctionExplorerStates.length >
                                    0 && (_jsxs(_Fragment, { children: [queryFunctionsState.treeData?.rootIds.length !== 0 && (_jsx("div", { className: "query-builder__functions-explorer__separator" })), queryFunctionsState.dependencyFunctionExplorerStates.map((funcExplorerState) => (_jsx(QueryBuilderFunctionsExplorerListEntry, { element: funcExplorerState.functionAnalysisInfo }, funcExplorerState.uuid)))] }))] }))] })] }));
});
//# sourceMappingURL=QueryBuilderFunctionsExplorerPanel.js.map