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 { useState, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { Dialog, CustomSelectorInput, createFilter, compareLabelFn, clsx, PanelDivider, } from '@finos/legend-art';
import { createClassMapping, createEnumerationMapping, getAllMappingElements, MappingEditorState, BASIC_SET_IMPLEMENTATION_TYPE, } from '../../../../stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js';
import { guaranteeNonNullable, UnsupportedOperationError, } from '@finos/legend-shared';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { fromElementPathToMappingElementId, Class, Enumeration, Association, PrimitiveType, } from '@finos/legend-graph';
import { buildElementOption, getPackageableElementOptionFormatter, } from '@finos/legend-lego/graph-editor';
export const NewMappingElementModal = observer(() => {
    const editorStore = useEditorStore();
    const applicationStore = editorStore.applicationStore;
    const mappingEditorState = editorStore.tabManagerState.getCurrentEditorState(MappingEditorState);
    const spec = mappingEditorState.newMappingElementSpec;
    // ID
    const mappingIdInputRef = useRef(null);
    const [id, setId] = useState('');
    const handleIdChange = (event) => setId(event.target.value);
    const mapping = mappingEditorState.mapping;
    const mappingIds = getAllMappingElements(mapping).map((mappingElement) => mappingElement.id.value);
    const isMappingIdUnique = !mappingIds.includes(id);
    const showId = spec?.target &&
        mappingIds.includes(fromElementPathToMappingElementId(spec.target.path));
    // Target
    const targetSelectorRef = useRef(null);
    const options = [
        ...editorStore.graphManagerState.usableEnumerations.map(buildElementOption),
        ...editorStore.graphManagerState.usableAssociations.map(buildElementOption),
        ...editorStore.graphManagerState.usableClasses.map(buildElementOption),
    ].sort(compareLabelFn);
    const filterOption = createFilter({
        ignoreCase: true,
        ignoreAccents: false,
        stringify: (option) => option.data.value.path,
    });
    const selectedOption = spec?.target
        ? {
            label: spec.target.name,
            value: spec.target,
        }
        : null;
    const handleTargetChange = (val) => {
        mappingEditorState.createMappingElement({
            target: val?.value,
            showTarget: true,
            openInAdjacentTab: Boolean(spec?.openInAdjacentTab),
        });
        const suggestedId = val?.value
            ? fromElementPathToMappingElementId(val.value.path)
            : '';
        setId(suggestedId && !mappingIds.includes(suggestedId) ? suggestedId : '');
    };
    // Class Mapping Type
    const classMappingTypeSelectorRef = useRef(null);
    const classMappingTypeOptions = [
        { value: BASIC_SET_IMPLEMENTATION_TYPE.INSTANCE, label: 'Instance' },
        { value: BASIC_SET_IMPLEMENTATION_TYPE.OPERATION, label: 'Operation' },
    ];
    const initialClassMappingType = guaranteeNonNullable(classMappingTypeOptions[0]);
    const [classMappingType, setClassMappingType] = useState(initialClassMappingType);
    const changeClassMappingType = (val) => setClassMappingType(val);
    // Dialog actions
    const handleClose = () => mappingEditorState.setNewMappingElementSpec(undefined);
    const handleEnter = () => {
        if (spec) {
            const suggestedId = spec.target
                ? fromElementPathToMappingElementId(spec.target.path)
                : '';
            setId(suggestedId && !mappingIds.includes(suggestedId) ? suggestedId : '');
            setClassMappingType(initialClassMappingType);
            // Set the focus properly depending on which input elements are shown
            if (spec.showTarget) {
                targetSelectorRef.current?.focus();
            }
            else {
                if (showId) {
                    mappingIdInputRef.current?.focus();
                }
                else if (spec.target instanceof Class) {
                    classMappingTypeSelectorRef.current?.focus();
                }
            }
        }
    };
    // Submit button
    const disableCreateButton = !spec?.target ||
        !isMappingIdUnique ||
        !id ||
        (spec.target instanceof Class && !classMappingType);
    const handleSubmit = () => {
        if (spec) {
            if (id && spec.target) {
                let newMappingElement = undefined;
                if (spec.target instanceof Class) {
                    if (classMappingType?.value) {
                        newMappingElement = createClassMapping(mapping, id, spec.target, classMappingType.value, editorStore);
                    }
                }
                else if (spec.target instanceof Enumeration) {
                    newMappingElement = createEnumerationMapping(mapping, id, spec.target, PrimitiveType.STRING);
                }
                else if (spec.target instanceof Association) {
                    throw new UnsupportedOperationError();
                }
                if (spec.postSubmitAction) {
                    spec.postSubmitAction(newMappingElement);
                }
                if (newMappingElement) {
                    mappingEditorState.openMappingElement(newMappingElement, spec.openInAdjacentTab);
                }
            }
            handleClose();
        }
    };
    // Title
    const titleText = spec
        ? spec.showTarget
            ? 'Create New Mapping Element'
            : `Create New ${spec.target instanceof Class
                ? 'Class'
                : spec.target instanceof Enumeration
                    ? 'Enumeration'
                    : 'Association'} Mapping ${spec.target ? `for ${spec.target.name}` : ''}`
        : undefined;
    return (_jsxs(Dialog, { open: Boolean(spec), onClose: handleClose, classes: {
            container: 'search-modal__container',
        }, slotProps: {
            transition: {
                onEnter: handleEnter,
            },
            paper: {
                classes: {
                    root: 'search-modal__inner-container',
                },
            },
        }, children: [spec && (_jsxs("form", { onSubmit: (event) => {
                    event.preventDefault();
                    handleSubmit();
                }, className: clsx('modal search-modal new-mapping-element-modal', {
                    'modal--dark': true,
                }), children: [titleText && _jsx("div", { className: "modal__title", children: titleText }), spec.showTarget && (_jsx(CustomSelectorInput, { inputRef: targetSelectorRef, options: options, filterOption: filterOption, onChange: handleTargetChange, value: selectedOption, formatOptionLabel: getPackageableElementOptionFormatter({}), placeholder: "Choose a target", isClearable: true, darkMode: !applicationStore.layoutService
                            .TEMPORARY__isLightColorThemeEnabled })), showId && (_jsxs("div", { children: [_jsx(PanelDivider, {}), "Default ID could not be used, please specify one:", _jsx(PanelDivider, {}), _jsx("input", { className: clsx('input new-mapping-element-modal__id-input', {
                                    'input--dark': true,
                                }), ref: mappingIdInputRef, spellCheck: false, value: id, onChange: handleIdChange, placeholder: "Mapping element ID" })] })), spec.target instanceof Class && (_jsxs(_Fragment, { children: [_jsx(PanelDivider, {}), _jsx(CustomSelectorInput, { inputRef: classMappingTypeSelectorRef, options: classMappingTypeOptions, onChange: changeClassMappingType, value: classMappingType, darkMode: !applicationStore.layoutService
                                    .TEMPORARY__isLightColorThemeEnabled, placeholder: "Choose a class mapping type" })] })), _jsx(PanelDivider, {}), _jsx("div", { className: "search-modal__actions", children: _jsx("button", { className: clsx('btn btn--primary', {
                                'btn--dark': true,
                            }), disabled: disableCreateButton, children: "Create" }) })] })), !spec && _jsx("div", {})] }));
});
//# sourceMappingURL=NewMappingElementModal.js.map