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 { observer } from 'mobx-react-lite';
import { Dialog, BlankPanelContent, CustomSelectorInput, PlusIcon, BlankPanelPlaceholder, Modal, ModalBody, ModalFooter, ModalHeader, ModalFooterButton, PanelFormValidatedTextField, QuestionCircleIcon, PanelFormSection, clsx, } from '@finos/legend-art';
import { VariableExpression, GenericTypeExplicitReference, GenericType, PrimitiveType, Multiplicity, getMultiplicityPrettyDescription, isValidIdentifier, } from '@finos/legend-graph';
import { useApplicationStore } from '@finos/legend-application';
import { variableExpression_setName } from '../stores/shared/ValueSpecificationModifierHelper.js';
import { LambdaParameterState } from '../stores/shared/LambdaParameterState.js';
import { LambdaParameterValuesEditor } from './shared/LambdaParameterValuesEditor.js';
import { VariableViewer } from './shared/QueryBuilderVariableSelector.js';
import { QUERY_BUILDER_TEST_ID } from '../__lib__/QueryBuilderTesting.js';
import { QUERY_BUILDER_DOCUMENTATION_KEY } from '../__lib__/QueryBuilderDocumentation.js';
import { useCallback, useState } from 'react';
import { buildElementOption, getPackageableElementOptionFormatter, } from '@finos/legend-lego/graph-editor';
import { deepClone } from '@finos/legend-shared';
import { BasicValueSpecificationEditor } from './shared/BasicValueSpecificationEditor.js';
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../graph/QueryBuilderMetaModelConst.js';
import { createSupportedFunctionExpression } from '../stores/shared/ValueSpecificationEditorHelper.js';
const buildMultiplicityOption = (multiplicity) => ({
    label: getMultiplicityPrettyDescription(multiplicity),
    value: multiplicity,
});
const VariableExpressionEditor = observer((props) => {
    // main state
    const { queryBuilderState, lambdaParameterState } = props;
    const applicationStore = useApplicationStore();
    const queryParametersState = queryBuilderState.parametersState;
    const allVariableNames = queryBuilderState.allVariableNames;
    const isCreating = !queryParametersState.parameterStates.includes(lambdaParameterState);
    const varState = lambdaParameterState.parameter;
    // type
    const stateType = lambdaParameterState.variableType ?? PrimitiveType.STRING;
    const [selectedType, setSelectedType] = useState(buildElementOption(stateType));
    const typeOptions = queryBuilderState.graphManagerState.graph.primitiveTypes
        .map(buildElementOption)
        .concat(queryBuilderState.graphManagerState.graph.enumerations.map(buildElementOption));
    const changeType = (val) => {
        setSelectedType(val);
    };
    // multiplicity
    const stateMultiplicity = varState.multiplicity;
    const [selectedMultiplicity, setSelectedMultiplicity] = useState(buildMultiplicityOption(stateMultiplicity));
    const validParamMultiplicityList = [
        Multiplicity.ONE,
        Multiplicity.ZERO_ONE,
        Multiplicity.ZERO_MANY,
    ];
    const multilicityOptions = validParamMultiplicityList.map(buildMultiplicityOption);
    const changeMultiplicity = (val) => {
        setSelectedMultiplicity(val);
    };
    // name
    const stateName = varState.name;
    const [selectedName, setSelectedName] = useState(stateName);
    const [isNameValid, setIsNameValid] = useState(true);
    const [hasEditedName, setHasEditedName] = useState(false);
    const nameInputRef = useCallback((ref) => {
        ref?.focus();
    }, []);
    const [defaultMilestoningValue, setDefaultMilestoningValue] = useState(deepClone(lambdaParameterState.value));
    const isMilestoningParameter = queryBuilderState.milestoningState.isMilestoningParameter(lambdaParameterState.parameter);
    const getValidationMessage = (input) => !hasEditedName
        ? undefined
        : !input
            ? `Parameter name can't be empty`
            : allVariableNames.filter((e) => e === input).length > 0 &&
                input !== stateName
                ? 'Parameter name already exists'
                : isValidIdentifier(input, true) === false
                    ? 'Parameter name must be text with no spaces and not start with an uppercase letter or number'
                    : undefined;
    // modal lifecycle actions
    const handleCancel = () => {
        queryParametersState.setSelectedParameter(undefined);
    };
    const handleApply = () => {
        lambdaParameterState.changeVariableType(selectedType.value);
        lambdaParameterState.changeMultiplicity(varState, selectedMultiplicity.value);
        variableExpression_setName(varState, selectedName);
        if (isCreating) {
            queryParametersState.addParameter(lambdaParameterState);
        }
        if (isMilestoningParameter) {
            queryBuilderState.milestoningState.updateMilestoningParameterValue(lambdaParameterState.parameter, defaultMilestoningValue);
        }
        handleCancel();
    };
    return (_jsx(Dialog, { open: Boolean(lambdaParameterState), onClose: handleCancel, classes: {
            root: 'editor-modal__root-container',
            container: 'editor-modal__container',
            paper: 'editor-modal__content',
        }, children: _jsxs(Modal, { darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, className: "editor-modal query-builder__variables__modal", children: [_jsx(ModalHeader, { title: `${isCreating ? 'Create Parameter' : 'Update Parameter'}` }), _jsxs(ModalBody, { className: "query-builder__variables__modal__body", children: [_jsx(PanelFormValidatedTextField, { name: "Parameter Name", prompt: "Name of the parameter. Should be descriptive of its purpose.", value: selectedName, update: (value) => {
                                setSelectedName(value ?? '');
                                setHasEditedName(true);
                            }, validate: getValidationMessage, onValidate: (issue) => setIsNameValid(!issue && selectedName.length > 0), isReadOnly: false, ref: nameInputRef }), _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Type" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Data type of the parameter." }), _jsx(CustomSelectorInput, { placeholder: "Choose a type...", options: typeOptions, onChange: changeType, value: selectedType, darkMode: !applicationStore.layoutService
                                        .TEMPORARY__isLightColorThemeEnabled, formatOptionLabel: getPackageableElementOptionFormatter({
                                        darkMode: !applicationStore.layoutService
                                            .TEMPORARY__isLightColorThemeEnabled,
                                    }) })] }), _jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Multiplicity" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "The multiplity determines how many values a parameter can have. Default is set to mandatory single vlue." }), _jsx(CustomSelectorInput, { placeholder: "Choose a multiplicity...", options: multilicityOptions, onChange: changeMultiplicity, value: selectedMultiplicity, hasError: !validParamMultiplicityList.includes(selectedMultiplicity.value), darkMode: !applicationStore.layoutService
                                        .TEMPORARY__isLightColorThemeEnabled })] }), isMilestoningParameter && defaultMilestoningValue && (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Value" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Choose a default value for this milestoning parameter" }), _jsx("div", { className: "query-builder__variable-editor", children: _jsx(BasicValueSpecificationEditor, { valueSpecification: defaultMilestoningValue, setValueSpecification: (val) => {
                                            setDefaultMilestoningValue(deepClone(val));
                                        }, graph: queryBuilderState.graphManagerState.graph, observerContext: queryBuilderState.observerContext, typeCheckOption: {
                                            expectedType: selectedType.value,
                                            match: selectedType.value === PrimitiveType.DATETIME,
                                        }, resetValue: () => {
                                            const now = createSupportedFunctionExpression(QUERY_BUILDER_SUPPORTED_FUNCTIONS.NOW, PrimitiveType.DATETIME);
                                            setDefaultMilestoningValue(now);
                                            queryBuilderState.milestoningState.updateMilestoningParameterValue(lambdaParameterState.parameter, now);
                                        } }) })] }))] }), _jsxs(ModalFooter, { children: [_jsx(ModalFooterButton, { text: isCreating ? 'Create' : 'Update', disabled: !isNameValid, onClick: handleApply }), _jsx(ModalFooterButton, { onClick: handleCancel, text: "Cancel", type: "secondary" })] })] }) }));
});
export const QueryBuilderParametersPanel = observer((props) => {
    const { queryBuilderState } = props;
    const isReadOnly = !queryBuilderState.isQuerySupported;
    const queryParameterState = queryBuilderState.parametersState;
    const parametersFilteredOutMilestoning = queryParameterState.parameterStates.filter((paramState) => !queryBuilderState.milestoningState.isMilestoningParameter(paramState.parameter));
    const seeDocumentation = () => queryBuilderState.applicationStore.assistantService.openDocumentationEntry(QUERY_BUILDER_DOCUMENTATION_KEY.QUESTION_HOW_TO_ADD_PARAMETERS_TO_QUERY);
    const addParameter = () => {
        if (!isReadOnly && !queryBuilderState.isParameterSupportDisabled) {
            const parmaterState = new LambdaParameterState(new VariableExpression('', queryBuilderState.graphManagerState.graph.getMultiplicity(1, 1), GenericTypeExplicitReference.create(new GenericType(PrimitiveType.STRING))), queryBuilderState.observerContext, queryBuilderState.graphManagerState.graph);
            queryParameterState.setSelectedParameter(parmaterState);
            parmaterState.mockParameterValue();
        }
    };
    return (_jsxs("div", { "data-testid": QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PARAMETERS, className: "panel query-builder__variables", children: [_jsxs("div", { className: "panel__header", children: [_jsxs("div", { className: "panel__header__title", children: [_jsx("div", { className: "panel__header__title__label", children: "parameters" }), _jsx("div", { onClick: !queryBuilderState.applicationStore.assistantService.isDisabled
                                    ? seeDocumentation
                                    : undefined, className: clsx('query-builder__variables__info', {
                                    'query-builder__variables__info--assistant-disabled': queryBuilderState.applicationStore.assistantService
                                        .isDisabled,
                                }), title: `Parameters are variables assigned to your query. They are dynamic in nature and can change for each execution.`, children: _jsx(QuestionCircleIcon, {}) })] }), !isReadOnly && !queryBuilderState.isParameterSupportDisabled && (_jsx("div", { className: "panel__header__actions", children: _jsx("button", { className: "panel__header__action", tabIndex: -1, onClick: addParameter, title: "Add Parameter", children: _jsx(PlusIcon, {}) }) }))] }), _jsxs("div", { className: "panel__content query-builder__variables__content", children: [!queryBuilderState.isParameterSupportDisabled && (_jsxs(_Fragment, { children: [Boolean(parametersFilteredOutMilestoning.length) &&
                                parametersFilteredOutMilestoning.map((pState) => (_jsx(VariableViewer, { variable: pState.parameter, isReadOnly: isReadOnly, queryBuilderState: queryBuilderState, actions: {
                                        editVariable: () => queryParameterState.setSelectedParameter(pState),
                                        deleteVariable: () => queryParameterState.removeParameter(pState),
                                    } }, pState.uuid))), !parametersFilteredOutMilestoning.length && (_jsx(BlankPanelPlaceholder, { text: "Add a parameter", disabled: isReadOnly, onClick: addParameter, clickActionType: "add", previewText: "No parameter", tooltipText: "Click to add a new parameter" }))] })), queryBuilderState.isParameterSupportDisabled && (_jsx(BlankPanelContent, { children: "Parameters are not supported" }))] }), queryParameterState.selectedParameter && (_jsx(VariableExpressionEditor, { queryBuilderState: queryBuilderState, lambdaParameterState: queryParameterState.selectedParameter })), queryParameterState.parameterValuesEditorState.showModal && (_jsx(LambdaParameterValuesEditor, { graph: queryBuilderState.graphManagerState.graph, observerContext: queryBuilderState.observerContext, lambdaParametersState: queryParameterState }))] }));
});
//# sourceMappingURL=QueryBuilderParametersPanel.js.map