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, useMemo, useCallback } from 'react';
import { observer } from 'mobx-react-lite';
import { flowResult, runInAction } from 'mobx';
import { getElementIcon } from '../../../ElementIconUtils.js';
import { useDrop } from 'react-dnd';
import { FileGenerationEditorState } from '../../../../stores/editor/editor-state/element-editor-state/FileGenerationEditorState.js';
import { UnsupportedOperationError, debounce, guaranteeNonNullable, prettyCONSTName, } from '@finos/legend-shared';
import { ResizablePanelGroup, ResizablePanel, ResizablePanelSplitter, ResizablePanelSplitterLine, CustomSelectorInput, PencilIcon, RefreshIcon, TimesIcon, LockIcon, SaveIcon, PanelDropZone, Panel, PanelContent, PanelFormSection, PanelHeader, PanelFormTextField, PanelFormBooleanField, Button, } from '@finos/legend-art';
import { CORE_DND_TYPE, } from '../../../../stores/editor/utils/DnDUtils.js';
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
import { useEditorStore } from '../../EditorStoreProvider.js';
import { GenerationPropertyItemType, PackageableElementReference, PackageableElementExplicitReference, isValidFullPath, resolvePackagePathAndElementName, getNullableFileGenerationConfig, } from '@finos/legend-graph';
import { useApplicationStore } from '@finos/legend-application';
import { fileGeneration_addScopeElement, fileGeneration_changeScopeElement, fileGeneration_deleteScopeElement, fileGeneration_setGenerationOutputPath, } from '../../../../stores/graph-modifier/DSL_Generation_GraphModifierHelper.js';
import { FileSystemViewer } from './FileSystemViewer.js';
const FileGenerationScopeEditor = observer((props) => {
    const { isReadOnly, fileGenerationState, regenerate } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const fileGeneration = fileGenerationState.fileGeneration;
    const scopeElements = fileGeneration.scopeElements;
    const scopeElementPath = (element) => element instanceof PackageableElementReference
        ? element.value.path
        : element;
    // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
    const [showEditInput, setShowEditInput] = useState(false);
    const [itemValue, setItemValue] = useState(undefined);
    const hideAddOrEditItemInput = () => {
        setShowEditInput(false);
        setItemValue('');
    };
    const showEditItemInput = (value, idx) => () => {
        setItemValue(scopeElementPath(value));
        setShowEditInput(idx);
    };
    const showAddItemInput = () => {
        setShowEditInput(true);
        setItemValue('');
    };
    const deleteScopeElement = (scopeElement) => {
        fileGeneration_deleteScopeElement(fileGeneration, scopeElement);
        regenerate()?.catch(applicationStore.alertUnhandledError);
    };
    const changeItemInputValue = (event) => setItemValue(event.target.value);
    const isDisabled = Boolean(isReadOnly ||
        !itemValue ||
        scopeElements
            .map((element) => scopeElementPath(element))
            .includes(itemValue));
    const addValue = () => {
        if (itemValue && !isReadOnly) {
            regenerate.cancel();
            const element = editorStore.graphManagerState.graph.getNullableElement(itemValue, true);
            fileGenerationState.addScopeElement(element ?? itemValue);
            regenerate()?.catch(applicationStore.alertUnhandledError);
            hideAddOrEditItemInput();
        }
    };
    const updateValue = (value) => () => {
        if (itemValue &&
            !isReadOnly &&
            !scopeElements
                .map((element) => scopeElementPath(element))
                .includes(itemValue)) {
            const element = editorStore.graphManagerState.graph.getNullableElement(itemValue, true);
            if (element) {
                regenerate.cancel();
                fileGeneration_changeScopeElement(fileGeneration, value, PackageableElementExplicitReference.create(element));
                regenerate()?.catch(applicationStore.alertUnhandledError);
            }
        }
        hideAddOrEditItemInput();
    };
    return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Scope" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Specifies the list of packages and elements that will determine elements to get generated" }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [scopeElements.map((value, idx) => (
                            // NOTE: since the value must be unique, we will use it as the key
                            _jsx("div", { className: showEditInput === idx
                                    ? 'panel__content__form__section__list__new-item'
                                    : 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx(Button, { className: "panel__content__form__section__list__new-item__add-btn", disabled: isDisabled, onClick: updateValue(value), text: "save" }), _jsx(Button, { className: "panel__content__form__section__list__new-item__cancel-btn", disabled: isReadOnly, onClick: hideAddOrEditItemInput, text: "cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "panel__content__form__section__list__item__value file-generation-editor__configuration__content__scope", children: [_jsx("div", { className: "file-generation-editor__configuration__content__scope__icon", children: getElementIcon(value instanceof PackageableElementReference
                                                        ? value.value
                                                        : undefined, editorStore) }), _jsx("div", { className: "file-generation-editor__configuration__content__scope__path", children: scopeElementPath(value) })] }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: () => deleteScopeElement(value), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, scopeElementPath(value)))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isDisabled, onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), !scopeElements.length && (_jsx("div", { className: "panel__content__form__section__list__empty", children: "No path specified" })), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] })] }));
});
const GenerationStringPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    // If there is no default value the string will be 'null'. We will treat it as an empty string
    const defaultValue = property.defaultValue === 'null' ? '' : property.defaultValue;
    const value = getConfigValue(property.name) ?? defaultValue;
    const changeValue = (event) => update(property, event.target.value);
    return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: prettyCONSTName(property.name) }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx("input", { className: "panel__content__form__section__input", spellCheck: false, disabled: isReadOnly, value: value, onChange: changeValue })] }));
});
const GenerationIntegerPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    const defaultValue = JSON.parse(property.defaultValue);
    const value = getConfigValue(property.name) ?? defaultValue;
    const changeValue = (event) => update(property, event.target.value);
    return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__number-input", spellCheck: false, type: "number", disabled: isReadOnly, value: value, onChange: changeValue })] }));
});
const GenerationBooleanPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    const defaultValue = JSON.parse(property.defaultValue);
    const value = getConfigValue(property.name) ?? defaultValue;
    return (_jsx(PanelFormBooleanField, { isReadOnly: isReadOnly, value: value, name: prettyCONSTName(property.name), prompt: property.description, update: (newValue) => {
            update(property, newValue);
        } }));
});
const GenerationEnumPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    const applicationStore = useApplicationStore();
    const getEnumLabel = (_enum) => isValidFullPath(_enum)
        ? resolvePackagePathAndElementName(_enum)[1]
        : _enum;
    const options = guaranteeNonNullable(property.items, 'Generation configuration description items for enum property item type is missing').enums.map((_enum) => ({ label: getEnumLabel(_enum), value: _enum }));
    const value = getConfigValue(property.name) ??
        property.defaultValue;
    const onChange = (val) => {
        if (val !== null && val.value !== value) {
            update(property, val.value);
        }
    };
    return (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", options: options, onChange: onChange, value: { label: getEnumLabel(value), value }, isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled, disabled: isReadOnly })] }));
});
const GenerationArrayPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    let defaultValue = [];
    // NOTE: hacking this because the backend send corrupted array string
    if (property.defaultValue !== '' && property.defaultValue !== '[]') {
        defaultValue = property.defaultValue
            .substring(1, property.defaultValue.length - 1)
            .split(',');
    }
    const arrayValues = getConfigValue(property.name) ?? defaultValue;
    // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
    const [showEditInput, setShowEditInput] = useState(false);
    const [itemValue, setItemValue] = useState('');
    const showAddItemInput = () => setShowEditInput(true);
    const showEditItemInput = (value, idx) => () => {
        setItemValue(value);
        setShowEditInput(idx);
    };
    const hideAddOrEditItemInput = () => {
        setShowEditInput(false);
        setItemValue('');
    };
    const changeItemInputValue = (event) => setItemValue(event.target.value);
    const addValue = () => {
        if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) {
            update(property, arrayValues.concat([itemValue]));
        }
        hideAddOrEditItemInput();
    };
    const updateValue = (idx) => () => {
        if (itemValue && !isReadOnly && !arrayValues.includes(itemValue)) {
            runInAction(() => {
                arrayValues[idx] = itemValue;
            });
            update(property, arrayValues);
        }
        hideAddOrEditItemInput();
    };
    const deleteValue = (idx) => () => {
        if (!isReadOnly) {
            runInAction(() => arrayValues.splice(idx, 1));
            update(property, [...arrayValues]);
            // Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry
            if (typeof showEditInput === 'number' && showEditInput > idx) {
                setShowEditInput(showEditInput - 1);
            }
        }
    };
    return (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [arrayValues.map((value, idx) => (
                            // NOTE: since the value must be unique, we will use it as the key
                            _jsx("div", { className: showEditInput === idx
                                    ? 'panel__content__form__section__list__new-item'
                                    : 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: updateValue(idx), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "panel__content__form__section__list__item__value", children: value }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: deleteValue(idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, value))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly || arrayValues.includes(itemValue), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx(Button, { className: "panel__content__form__section__list__new-item__add-btn", disabled: isReadOnly, onClick: showAddItemInput, text: "Add Value" }) }))] })] }));
});
const GenerationMapPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    // Right now, always assume this is a map between STRING and STRING (might need to support STRING - INTEGER and STRING - BOOLEAN)
    const nonNullableDefaultValue = property.defaultValue === 'null' ? '{}' : property.defaultValue;
    const mapValues = (getConfigValue(property.name) ?? JSON.parse(nonNullableDefaultValue));
    // NOTE: `showEditInput` is either boolean (to hide/show the add value button) or a number (index of the item being edited)
    const [showEditInput, setShowEditInput] = useState(false);
    const [itemKey, setItemKey] = useState('');
    const [itemValue, setItemValue] = useState('');
    const showAddItemInput = () => setShowEditInput(true);
    const showEditItemInput = (key, value, idx) => () => {
        setItemKey(key);
        setItemValue(value);
        setShowEditInput(idx);
    };
    const hideAddOrEditItemInput = () => {
        setShowEditInput(false);
        setItemKey('');
        setItemValue('');
    };
    const changeItemInputKey = (event) => setItemKey(event.target.value);
    const changeItemInputValue = (event) => setItemValue(event.target.value);
    const addValue = () => {
        if (itemValue &&
            itemKey &&
            !isReadOnly &&
            !Array.from(Object.keys(mapValues)).includes(itemKey)) {
            runInAction(() => {
                mapValues[itemKey] = itemValue;
            });
            update(property, mapValues);
        }
        hideAddOrEditItemInput();
    };
    const updateValue = (key) => () => {
        if (itemValue && !isReadOnly) {
            runInAction(() => {
                delete mapValues[key];
                mapValues[itemKey] = itemValue;
            });
            update(property, mapValues);
        }
        hideAddOrEditItemInput();
    };
    const deleteValue = (key, idx) => () => {
        if (!isReadOnly) {
            runInAction(() => delete mapValues[key]);
            update(property, mapValues);
            // Since we keep track of the value currently being edited using the index, we have to account for it as we delete entry
            if (typeof showEditInput === 'number' && showEditInput > idx) {
                setShowEditInput(showEditInput - 1);
            }
        }
    };
    return (_jsxs(PanelFormSection, { children: [_jsx("div", { className: "panel__content__form__section__header__label", children: property.name }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: property.description }), _jsxs("div", { className: "panel__content__form__section__list", children: [_jsxs("div", { className: "panel__content__form__section__list__items", "data-testid": LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS, children: [Array.from(Object.entries(mapValues)).map(([key, value], idx) => (
                            // NOTE: since the key must be unique, we will use it to generate the key
                            _jsx("div", { className: showEditInput === idx
                                    ? 'panel__content__form__section__list__new-item'
                                    : 'panel__content__form__section__list__item', children: showEditInput === idx ? (_jsxs(_Fragment, { children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemKey, onChange: changeItemInputKey }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: updateValue(key), tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "panel__content__form__section__list__item__value panel__content__form__section__list__item__value__map-item", children: [_jsx("span", { className: "panel__content__form__section__list__item__value__map-item__key", children: key }), _jsx("span", { className: "panel__content__form__section__list__item__value__map-item__separator", children: ":" }), _jsx("span", { className: "panel__content__form__section__list__item__value__map-item__value", children: value })] }), _jsxs("div", { className: "panel__content__form__section__list__item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__item__edit-btn", disabled: isReadOnly, onClick: showEditItemInput(key, value, idx), tabIndex: -1, children: _jsx(PencilIcon, {}) }), _jsx("button", { className: "panel__content__form__section__list__item__remove-btn", disabled: isReadOnly, onClick: deleteValue(key, idx), tabIndex: -1, children: _jsx(TimesIcon, {}) })] })] })) }, key))), showEditInput === true && (_jsxs("div", { className: "panel__content__form__section__list__new-item", children: [_jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemKey, onChange: changeItemInputKey }), _jsx("input", { className: "panel__content__form__section__input panel__content__form__section__list__new-item__input", spellCheck: false, disabled: isReadOnly, value: itemValue, onChange: changeItemInputValue }), _jsxs("div", { className: "panel__content__form__section__list__new-item__actions", children: [_jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly ||
                                                    Array.from(Object.keys(mapValues)).includes(itemKey), onClick: addValue, tabIndex: -1, children: "Save" }), _jsx("button", { className: "panel__content__form__section__list__new-item__cancel-btn btn btn--dark", disabled: isReadOnly, onClick: hideAddOrEditItemInput, tabIndex: -1, children: "Cancel" })] })] }))] }), showEditInput !== true && (_jsx("div", { className: "panel__content__form__section__list__new-item__add", children: _jsx("button", { className: "panel__content__form__section__list__new-item__add-btn btn btn--dark", disabled: isReadOnly, onClick: showAddItemInput, tabIndex: -1, children: "Add Value" }) }))] })] }));
});
export const GenerationPropertyEditor = observer((props) => {
    const { property, getConfigValue, isReadOnly, update } = props;
    switch (property.type) {
        case GenerationPropertyItemType.STRING:
            return (_jsx(GenerationStringPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        case GenerationPropertyItemType.INTEGER:
            return (_jsx(GenerationIntegerPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        case GenerationPropertyItemType.BOOLEAN:
            return (_jsx(GenerationBooleanPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        case GenerationPropertyItemType.ENUM:
            return (_jsx(GenerationEnumPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        case GenerationPropertyItemType.ARRAY:
            return (_jsx(GenerationArrayPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        case GenerationPropertyItemType.MAP:
            return (_jsx(GenerationMapPropertyEditor, { getConfigValue: getConfigValue, isReadOnly: isReadOnly, update: update, property: property }));
        default:
            throw new UnsupportedOperationError(`Can't generate editor for artifact generation property of type '${property.type}'`);
    }
});
export const FileGenerationConfigurationEditor = observer((props) => {
    const { isReadOnly, fileGenerationState, elementGenerationState } = props;
    const editorStore = useEditorStore();
    const applicationStore = useApplicationStore();
    const fileGeneration = fileGenerationState.fileGeneration;
    const fileGenerationConfiguration = editorStore.graphState.graphGenerationState.globalFileGenerationState.getFileGenerationConfiguration(fileGeneration.type).properties;
    const debouncedRegenerate = useMemo(() => debounce(() => flowResult(fileGenerationState.generate()), 500), [fileGenerationState]);
    const update = (generationProperty, newValue) => {
        debouncedRegenerate.cancel();
        fileGenerationState.updateFileGenerationParameters(fileGeneration, generationProperty, newValue);
        debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
    };
    const showFileGenerationModal = () => {
        elementGenerationState?.setShowNewFileGenerationModal(true);
    };
    const resetDefaultConfiguration = () => {
        debouncedRegenerate.cancel();
        fileGenerationState.resetGenerator();
        debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
    };
    // Drag and Drop
    const handleDrop = useCallback((item) => {
        const element = item.data.packageableElement;
        if (!isReadOnly &&
            !elementGenerationState &&
            !fileGenerationState.getScopeElement(element)) {
            debouncedRegenerate.cancel();
            fileGeneration_addScopeElement(fileGeneration, PackageableElementExplicitReference.create(element));
            debouncedRegenerate()?.catch(applicationStore.alertUnhandledError);
        }
    }, [
        applicationStore.alertUnhandledError,
        debouncedRegenerate,
        elementGenerationState,
        fileGeneration,
        fileGenerationState,
        isReadOnly,
    ]);
    const [{ isScopeElementDragOver }, dropConnector] = useDrop(() => ({
        accept: [
            CORE_DND_TYPE.PROJECT_EXPLORER_PACKAGE,
            CORE_DND_TYPE.PROJECT_EXPLORER_CLASS,
            CORE_DND_TYPE.PROJECT_EXPLORER_ENUMERATION,
        ],
        drop: (item) => handleDrop(item),
        collect: (monitor) => ({
            isScopeElementDragOver: monitor.isOver({ shallow: true }),
        }),
    }), [handleDrop]);
    const getConfigValue = (name) => getNullableFileGenerationConfig(fileGeneration, name)?.value;
    return (_jsxs(Panel, { className: "file-generation-editor__configuration", children: [_jsxs(PanelHeader, { children: [_jsx("div", { className: "panel__header__title", children: _jsx("div", { className: "panel__header__title__label", children: `${fileGeneration.type} configuration` }) }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action file-generation-editor__configuration__reset-btn", tabIndex: -1, disabled: isReadOnly || !fileGeneration.configurationProperties.length, onClick: resetDefaultConfiguration, title: "Reset to default configuration", children: _jsx(RefreshIcon, {}) }), Boolean(elementGenerationState) && (_jsx("button", { className: "panel__header__action", tabIndex: -1, disabled: isReadOnly, onClick: showFileGenerationModal, title: "Promote to file generation specification...", children: _jsx(SaveIcon, {}) }))] })] }), _jsx(PanelContent, { children: _jsx(PanelDropZone, { dropTargetConnector: dropConnector, isDragOver: isScopeElementDragOver && !elementGenerationState && !isReadOnly, children: _jsxs("div", { className: "file-generation-editor__configuration__content", children: [_jsx(FileGenerationScopeEditor, { fileGenerationState: fileGenerationState, regenerate: debouncedRegenerate, isReadOnly: isReadOnly || Boolean(elementGenerationState) }), _jsx(PanelFormTextField, { isReadOnly: isReadOnly, value: fileGeneration.generationOutputPath ?? '', name: "Generation Output Path", prompt: "Specifies the root path where files will be generated.\n                Defaults to the file specification path", update: (value) => fileGeneration_setGenerationOutputPath(fileGeneration, value ?? '') }), fileGenerationConfiguration.map((abstractGenerationProperty) => (_jsx(GenerationPropertyEditor, { update: update, isReadOnly: isReadOnly, getConfigValue: getConfigValue, property: abstractGenerationProperty }, abstractGenerationProperty.name +
                                abstractGenerationProperty.type)))] }) }) })] }));
});
export const FileGenerationEditor = observer(() => {
    const editorStore = useEditorStore();
    const fileGenerationEditorState = editorStore.tabManagerState.getCurrentEditorState(FileGenerationEditorState);
    const fileGeneration = fileGenerationEditorState.fileGeneration;
    const isReadOnly = fileGenerationEditorState.isReadOnly;
    return (_jsx("div", { className: "file-generation-editor", children: _jsxs(Panel, { children: [_jsx(PanelHeader, { children: _jsxs("div", { className: "panel__header__title", children: [isReadOnly && (_jsx("div", { className: "uml-element-editor__header__lock", children: _jsx(LockIcon, {}) })), _jsx("div", { className: "panel__header__title__label", children: "file generation" }), _jsx("div", { className: "panel__header__title__content", children: fileGeneration.name })] }) }), _jsx(PanelContent, { className: "file-generation-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsx(ResizablePanel, { size: 400, minSize: 300, children: _jsx(FileGenerationConfigurationEditor, { isReadOnly: isReadOnly, fileGenerationState: fileGenerationEditorState.fileGenerationState }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: _jsx(FileSystemViewer, { generatedFileState: fileGenerationEditorState.fileGenerationState }) })] }) })] }) }));
});
//# sourceMappingURL=FileGenerationEditor.js.map