import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useEffect } from "react";
import { Button, FormControl, FormGroup, FormControlLabel, FormLabel, IconButton, Select, TextField, Tab, Dialog, DialogContent, DialogTitle, DialogActions, Checkbox, Collapse, ButtonGroup, Fade, Typography, } from "@material-ui/core";
import Alert from "@material-ui/lab/Alert";
import Xarrow from "react-xarrows";
import { Pencil } from "mdi-material-ui";
import styled from "styled-components";
import { ArrowDownwardOutlined, ArrowUpwardOutlined, DeleteOutlined, AddBoxRounded } from "@material-ui/icons";
import { UndefinedDataDefinition } from "../../Common/Data/Definitions/UndefinedDataDefinition";
import ArrowDropDownOutlinedIcon from "@material-ui/icons/ArrowDropDownOutlined";
import ArrowDropUpOutlinedIcon from "@material-ui/icons/ArrowDropUpOutlined";
import { XDataType } from "../../Common/Data/XDataType";
import { TextIcon } from "../TextIcon";
import { TabContext, TabList, TabPanel } from "@material-ui/lab";
import { EditIcon } from "../Icon/EditIcon";
import { DataUtilities } from "../../Common/DataUtilities";
import { XValueEditor } from "../DataEditing";
import { EditModeObjectValueEditor } from "../DataEditing/Object";
import { DataDefEditLayer } from "./DataDefEditLayer";
import { AddFieldToDataStructure } from "../../Common/Data/ExecutionData/AddFieldToDataStructure";
import { DateDataDefinition } from "../../Common/Data/Definitions/DateDataDefinition";
import { StringDataDefinition } from "../../Common/Data/Definitions/StringDataDefinition";
import { NumberDataDefinition } from "../../Common/Data/Definitions/NumberDataDefinition";
import { BooleanDataDefinition } from "../../Common/Data/Definitions/BooleanDataDefinition";
const DataDefinitionDiv = styled.div `
    width: 100%;
    height: 100vh;
    overflow: auto;
    display: flex;
    flex-direction: column;

    .XDataDef-root {
        flex: 1;
    }
`;
const EditorDiv = styled.div `
    display: flex;
    flex-direction: row;
    width: 100%;
    padding-left: 5px;
    overflow: auto;
    height: 100%;
`;
const EditorTools = styled.div `
    margin-bottom: 15px;
`;
const DataEditorRow = styled.div `
    display: flex;
    flex-direction: row;
    position: relative;
    min-height: 52px;

    .data-field-type {
        min-width: 70px;
        text-align: center;
        text-transform: capitalize;
        background: #fcfcfe;
        padding: 10px 0px;
        border-radius: 4px;
        border: 1px solid #c2c2c3;
    }
    .data-field-list {
        min-width: 90px;
        font-size: 14px;
        text-align: center;
        text-transform: capitalize;
        background: #fcfcfe;
        padding: 10px 0px;
        border-radius: 4px;
        border: 1px solid #c2c2c3;
        color: black;
        align-items: center;
        display: flex;
        justify-content: center;
    }
`;
const DataEditorDefDiv = styled.div `
    display: flex;
    flex-direction: row;
    align-items: start;
    position: relative;
    width: 100%;
    > * {
        margin: 5px !important;
    }

    .DefEditor-select,
    .DefEditor-text .MuiOutlinedInput-input {
        padding: 10px;
        background: #fcfcfe;
    }
`;
const SchemaDiv = styled.div `
    display: flex;
    flex-direction: column;
    width: 600px;
    min-width: 600px;

    position: relative;

    .schema-section-title {
        padding: 15px;
        background: #d9dced;
        text-align: left;
        border-right: solid 2px #cbcee5;
    }
`;
const FieldsDefinitionDiv = styled.div `
    flex: 1;
    overflow: auto;
    padding: 20px 15px !important;
    border-right: solid 2px #ebedf6;
`;
const ExampleDataDiv = styled.div `
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: auto;
    min-width: 400px;
    .example-section-title {
        padding: 15px;
        background: #d9dced;
        text-align: left;
        white-space: pre;
    }
`;
const ValuesDiv = styled.div `
    flex: 1;
    overflow: auto;
    flex-direction: column;
    padding: 20px 15px !important;
`;
function useForceUpdate() {
    const [value, setValue] = useState(0); // integer state
    return () => setValue((value) => value + 1); // update the state to force render
}
export var IDefinitionEditorMode;
(function (IDefinitionEditorMode) {
    IDefinitionEditorMode["Definition"] = "Definition";
    IDefinitionEditorMode["JSON"] = "JSON";
    IDefinitionEditorMode["SCHEMA"] = "JSON SCHEMA";
})(IDefinitionEditorMode || (IDefinitionEditorMode = {}));
export const XDefinitionEditor = function (props) {
    const [value, setValue] = useState(props.definition.getValueObject());
    const [dataChanges, setDataChanges] = useState([]);
    const [mode, setMode] = useState(IDefinitionEditorMode.Definition);
    const [defError, setDefError] = useState("");
    const [openJSONModal, setOpenJSONModal] = useState(false);
    const [openSchemaModal, setOpenSchemaModal] = useState(false);
    const [openDataChangesModal, setOpenDataChangesModal] = useState(false);
    const [errorDialogOpen, setErrorDialogOpen] = useState(false);
    const forceUpdate = useForceUpdate();
    function validateUndefinedDefinition(fields) {
        let validation = true;
        for (let field of fields) {
            if (field instanceof UndefinedDataDefinition) {
                validation = false;
            }
            else {
                if (field.fields) {
                    validation = validateUndefinedDefinition(field.fields);
                }
            }
        }
        return validation;
    }
    const onChangeMode = (_event, value) => {
        const validation = validateUndefinedDefinition(props.definition.fields);
        if (validation === true) {
            setMode(value);
        }
        else {
            setDefError("Please delete all undefined definitions");
            setErrorDialogOpen(true);
        }
    };
    const detectChanges = (newJSON, oldJSONObj, path) => {
        let newJsonObj = JSON.parse(newJSON);
        if (!oldJSONObj) {
            oldJSONObj = props.definition.value;
        }
        if (!path) {
            path = "";
        }
        for (let field in newJsonObj) {
            let val = Reflect.get(newJsonObj, field);
            let checkVal = val;
            let isArray = false;
            if (Array.isArray(val)) {
                isArray = true;
                checkVal = val[0];
            }
            if (!(field in oldJSONObj)) {
                let addedDef = undefined;
                if (typeof checkVal === "string") {
                    // see if it is a date string
                    if (DataUtilities.isDateString(val)) {
                        let newDef = new DateDataDefinition();
                        if (isArray) {
                            //todo: handle date array
                            let dateArray = [];
                            for (let dString of val) {
                                dateArray.push(DataUtilities.getDateFromString(dString));
                            }
                            newDef.setListValue(dateArray);
                        }
                        else {
                            newDef.setValue(DataUtilities.getDateFromString(val));
                        }
                        newDef.name = field;
                        newDef.list = isArray;
                        newDef.owner = props.definition;
                        addedDef = newDef;
                    }
                    else {
                        let newDef = new StringDataDefinition();
                        if (isArray) {
                            newDef.setListValue(val);
                        }
                        else {
                            newDef.setValue(val);
                        }
                        newDef.name = field;
                        newDef.list = isArray;
                        newDef.owner = props.definition;
                        addedDef = newDef;
                    }
                }
                else if (typeof checkVal === "number") {
                    let newDef = new NumberDataDefinition();
                    if (isArray) {
                        newDef.setListValue(val);
                    }
                    else {
                        newDef.setValue(val);
                    }
                    newDef.name = field;
                    newDef.list = isArray;
                    newDef.owner = props.definition;
                    addedDef = newDef;
                }
                else if (typeof checkVal === "boolean") {
                    let newDef = new BooleanDataDefinition();
                    if (isArray) {
                        newDef.setListValue(val);
                    }
                    else {
                        newDef.setValue(val);
                    }
                    newDef.name = field;
                    newDef.list = isArray;
                    newDef.owner = props.definition;
                    addedDef = newDef;
                }
                if (addedDef) {
                    let newChange = new AddFieldToDataStructure(addedDef, path);
                    let changes = dataChanges;
                    changes.push(newChange);
                    setDataChanges(changes);
                }
            }
            else {
                if (val instanceof Object) {
                    let newPath = path.split(".");
                    newPath.push(field);
                    detectChanges(JSON.stringify(val), Reflect.get(oldJSONObj, field), newPath.join("."));
                }
            }
        }
    };
    const onToggleJSONModal = () => {
        setOpenJSONModal(!openJSONModal);
    };
    const onToggleSchemaModal = () => {
        setOpenSchemaModal(!openSchemaModal);
    };
    const handleErrorDialogClose = () => {
        setErrorDialogOpen(false);
    };
    return (_jsxs(DataDefinitionDiv, { children: [_jsxs(TabContext, Object.assign({ value: mode }, { children: [_jsxs(TabList, Object.assign({ onChange: onChangeMode, indicatorColor: "primary", textColor: "primary" }, { children: [_jsx(Tab, { value: IDefinitionEditorMode.Definition, icon: _jsx(TextIcon, { name: "D" }, void 0), label: "Definition", wrapped: true, id: IDefinitionEditorMode.Definition, "aria-controls": `wrapped-tabpanel-${IDefinitionEditorMode.Definition}` }, void 0),
                            _jsx(Tab, { value: IDefinitionEditorMode.JSON, icon: _jsx(TextIcon, { name: "J" }, void 0), label: "JSON", wrapped: true, id: IDefinitionEditorMode.JSON, "aria-controls": `wrapped-tabpanel-${IDefinitionEditorMode.JSON}` }, void 0),
                            _jsx(Tab, { value: IDefinitionEditorMode.SCHEMA, icon: _jsx(TextIcon, { name: "S" }, void 0), label: "JSON SCHEMA", wrapped: true, id: IDefinitionEditorMode.SCHEMA, "aria-controls": `wrapped-tabpanel-${IDefinitionEditorMode.SCHEMA}` }, void 0)] }), void 0),
                    _jsx(TabPanel, Object.assign({ value: IDefinitionEditorMode.Definition, classes: { root: "XDataDef-root" } }, { children: _jsxs(EditorDiv, { children: [_jsxs(SchemaDiv, { children: [_jsx(Typography, Object.assign({ variant: "h4", align: "center", color: "primary", className: "schema-section-title" }, { children: "Schema" }), void 0),
                                        _jsx(FieldsDefinitionDiv, { children: _jsx(SubFieldsEditor, { fields: props.definition.fields, data: props.definition, onUpdate: forceUpdate, readOnly: props.readOnly }, void 0) }, void 0)] }, void 0),
                                _jsxs(ExampleDataDiv, { children: [_jsx(Typography, Object.assign({ variant: "h4", align: "center", color: "primary", className: "example-section-title" }, { children: "Example Data" }), void 0),
                                        _jsx(ValuesDiv, { children: _jsx(SubValues, { fields: props.definition.fields, data: props.definition, value: value, onUpdate: (newValue) => {
                                                    let newDefValue = Object.assign(Object.assign({}, props.definition.value), newValue);
                                                    setValue(newDefValue);
                                                    props.definition.value = newDefValue;
                                                    forceUpdate();
                                                }, readOnly: props.readOnly }, void 0) }, void 0)] }, void 0)] }, void 0) }), void 0),
                    _jsxs(TabPanel, Object.assign({ value: IDefinitionEditorMode.JSON, classes: { root: "XDataDef-root" } }, { children: [_jsx(EditorTools, { children: _jsx(Button, Object.assign({ variant: "contained", color: "primary", startIcon: _jsx(EditIcon, {}, void 0), onClick: onToggleJSONModal }, { children: "Edit JSON" }), void 0) }, void 0),
                            _jsx(TextField, { multiline: true, value: props.definition.toJSONObject(), variant: "outlined", fullWidth: true, InputProps: {
                                    readOnly: true,
                                } }, void 0),
                            _jsx(EditModal, { open: openJSONModal, value: props.definition.toJSONObject(), onEdit: (value) => {
                                    try {
                                        let json = JSON.stringify(JSON.parse(value));
                                        detectChanges(json);
                                        setOpenDataChangesModal(true);
                                        // props.definition.mergeJSON(JSON.stringify(json), true, true);
                                    }
                                    catch (error) {
                                        setDefError(String(error));
                                        setErrorDialogOpen(true);
                                    }
                                }, onClose: () => setOpenJSONModal(false) }, void 0)] }), void 0),
                    _jsxs(TabPanel, Object.assign({ value: IDefinitionEditorMode.SCHEMA, classes: { root: "XDataDef-root" } }, { children: [_jsx(EditorTools, { children: _jsx(Button, Object.assign({ variant: "contained", color: "primary", startIcon: _jsx(EditIcon, {}, void 0), onClick: onToggleSchemaModal }, { children: "Edit JSON Schema" }), void 0) }, void 0),
                            _jsx(TextField, { multiline: true, value: props.definition.toJSONSchema(), variant: "outlined", fullWidth: true, InputProps: {
                                    readOnly: true,
                                } }, void 0),
                            _jsx(EditModal, { open: openSchemaModal, value: props.definition.toJSONSchema(), onEdit: (value) => {
                                    try {
                                        let json = JSON.parse(value);
                                        props.definition.mergeJSONSchema(JSON.stringify(json));
                                    }
                                    catch (error) {
                                        setDefError(String(error));
                                        setErrorDialogOpen(true);
                                    }
                                }, onClose: () => setOpenSchemaModal(false) }, void 0)] }), void 0)] }), void 0),
            _jsx(Dialog, Object.assign({ onClose: handleErrorDialogClose, "aria-labelledby": "simple-dialog-title", open: errorDialogOpen }, { children: _jsx(Alert, Object.assign({ severity: "error" }, { children: defError }), void 0) }), void 0),
            _jsx(DataChangesModal, { open: openDataChangesModal, data: dataChanges, onUpdate: (changes) => {
                    console.log(changes);
                }, onClose: () => setOpenDataChangesModal(false) }, void 0)] }, void 0));
};
const SubFieldsWrapper = styled.div `
    ${(props) => props.isPadding &&
    `
        padding-left: 15px;
        margin-left: 15px;
        // border-left: solid 1px blue;
    `};
    .field-parent-editor {
        border-bottom: solid 1px #c4c4c4;
    }

    .MuiFormControl-root.field-name {
        width: 100%;
    }
    .DefEditor-checkboxLabel.MuiFormControlLabel-root {
        height: 39px;
        padding-right: 10px;
        border-radius: 3px;
        border: 1px solid #c4c4c4;
    }
    .add-new-field {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        .MuiButton-root {
            min-width: 34px;
            padding: 0;
            margin: 5px 0;
            color: rgb(165 165 165);
        }
        div {
            background: #f1f1f1;
            border-radius: 5px;
            margin: 5px 0;
        }
        .add-new-field-name {
            width: calc(100% - 250px);
        }
        .add-new-field-type {
            width: 93px;
        }
        .add-new-field-list {
            width: 97px;
        }
    }
    .add-new-field:hover {
        cursor: pointer;
    }
`;
const ValuesTableWrapperDiv = styled.div `
    position: relative;
`;
const ValuesTableDiv = styled.div `
    display: flex;
    align-items: flex-start;
    padding: 10px;
    background: #fcfcfe;

    ${(props) => props.height &&
    `
        height: ${props.height}px;
        overflow: auto;
        border-bottom: solid 1px #c4c4c4;
    `};

    .MuiTypography-h6 {
        margin-right: 10px;
    }

    .MuiInputBase-input,
    .MuiInputBase-input,
    .MuiOutlinedInput-input {
        font-family: Inter !important;
        font-size: 12px !important;
        font-style: normal;
        font-weight: 400 !important;
        line-height: 17px !important;
        letter-spacing: 0px;
        text-align: left;
        color: rgba(39, 41, 50, 0.8);
    }

    .MuiOutlinedInput-input {
        padding: 6px 12px;
        background: rgba(64, 80, 166, 0.05);
        height: 20px;
    }

    .MuiOutlinedInput-notchedOutline {
        border: none;
        border-bottom: solid 1px rgba(64, 80, 166, 0.35);
        border-radius: 0;
    }

    .MuiFormControl-root {
        display: flex;
    }

    .MuiSwitch-root {
        height: 25px !important;
        width: 40px !important;
        padding: 0;
        border-radius: 20px;
    }

    .MuiSwitch-switchBase {
        padding: 2px !important;

        &.Mui-checked {
            transform: translateX(15px) !important;
        }
    }

    input[type="date"],
    input[type="datetime-local"] {
        position: relative;

        &::-webkit-calendar-picker-indicator {
            position: absolute;
            right: 0;
            top: 50%;
            transform: translateY(-50%);
            height: 20px;
            width: 20px;
            opacity: 0;
        }
        &:hover::-webkit-calendar-picker-indicator {
            opacity: 1;
        }
    }

    input[type="number"]::-webkit-outer-spin-button,
    input[type="number"]::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

    /* Firefox */
    input[type="number"] {
        -moz-appearance: textfield;
    }
`;
const SubValuesWrapper = styled.div `
    flex-direction: column;
    display: flex;
`;
const CollapseDiv = styled.div `
    width: 30px;
    margin-right: 15px;
    display: flex;
    align-items: start;
    .div-collapse {
        display: flex;
        align-items: center;
        width: 100%;
        height: 40px;
        background: #fcfcfe;
        border-radius: 5px;
        margin-top: 5px;
    }
`;
export const SubFieldsEditor = (props) => {
    const [newFieldName, setNewFieldName] = useState("");
    let prefixPath = props.path ? `${props.path}.` : "";
    const [error, setError] = useState(null);
    const createNewField = () => {
        try {
            DataUtilities.addDataDefinitionByPath(props.data, XDataType.UNDEFINED, props.path || "", newFieldName);
            setNewFieldName("");
            props.onUpdate();
            if (error) {
                setError(null);
            }
        }
        catch (e) {
            setError(e.message);
        }
    };
    return (_jsxs(SubFieldsWrapper, Object.assign({ isPadding: props.path }, { children: [props.fields.map((field, idx) => {
                return (_jsx("div", Object.assign({ className: "field-editor" }, { children: _jsx(FieldEditor, { data: props.data, field: field, path: `${prefixPath}${field.name}`, onUpdate: props.onUpdate, index: idx, isLast: idx === props.fields.length - 1, "data-testid": `${prefixPath}${field.name}`, readOnly: props.readOnly, parentId: `${props.path || ""}` }, void 0) }), `${field.name}_${idx}`));
            }),
            !props.readOnly && (_jsxs("div", Object.assign({ className: "add-new-field" }, { children: [_jsx(Button, Object.assign({ onClick: createNewField }, { children: _jsx(AddBoxRounded, { fontSize: "large" }, void 0) }), void 0),
                    _jsx("div", { className: "add-new-field-name", onClick: createNewField }, void 0),
                    _jsx("div", { className: "add-new-field-type", onClick: createNewField }, void 0),
                    _jsx("div", { className: "add-new-field-list", onClick: createNewField }, void 0)] }), void 0))] }), void 0));
};
const DataValueAddTextDiv = styled.div `
    height: 52px;
`;
export const ValuesTable = (props) => {
    const [value, setValue] = useState(props.value);
    const onValueUpdate = (newValue) => {
        setValue(newValue);
        props.onUpdate(newValue);
    };
    return (_jsx(ValuesTableWrapperDiv, { children: _jsx(ValuesTableDiv, Object.assign({ height: props.readOnly
                ? 52 * (DataUtilities.getFieldsLevel(props.data, props.path, 2) - 2) + 1
                : 52 * (DataUtilities.getFieldsLevel(props.data, props.path, 2) - 1) + 1 }, { children: _jsx(EditModeObjectValueEditor, { forData: props.field, value: value, editMode: "inline", onUpdate: onValueUpdate, showFieldName: false }, void 0) }), void 0) }, void 0));
};
export const SubValues = (props) => {
    let prefixPath = props.path ? `${props.path}.` : "";
    return (_jsxs(SubValuesWrapper, { children: [props.fields.map((field, idx) => {
                return (_jsx(ValueEditor, { field: field, data: props.data, value: Reflect.get(props.value || {}, field.name), onUpdate: (newValue) => {
                        props.onUpdate(Object.assign(Object.assign({}, props.value), {
                            [field.name]: newValue,
                        }));
                    }, path: `${prefixPath}${field.name}`, showLabel: props.showLabel, noBorder: props.noBorder, noSetMinHeight: props.noSetMinHeight, readOnly: props.readOnly }, `${field.name}-${idx}`));
            }),
            _jsx(DataValueAddTextDiv, {}, void 0)] }, void 0));
};
const FieldNameDiv = styled.div `
    flex: 1;
    position: relative;
    .path-connector {
        position: absolute;
        bottom: -5px;
        left: 15px;
        width: 5px;
        height: 5px;
    }
`;
export const FieldControl = (props) => {
    let field = props.field;
    const [fieldName, setFieldName] = useState(field.name);
    const [showTools, setShowTools] = useState(false);
    const [error, setError] = useState(null);
    useEffect(() => {
        let validationError = DataUtilities.validateDataDefinitionNameByPath(props.data, props.path, fieldName, 1);
        if (!error && validationError) {
            setError(validationError);
        }
        else if (error && !validationError) {
            setError(null);
        }
    }, [error, props.data, props.path, fieldName]);
    const onUpdateFieldName = () => {
        if (field.name !== fieldName) {
            try {
                DataUtilities.changeDataDefinitionNameByPath(props.data, fieldName, props.path);
                props.onUpdate();
                setError(null);
            }
            catch (e) {
                setError(`Can not set the field name with ${fieldName}`);
                console.error("Error:", e);
            }
        }
    };
    const onUpdateChangeType = (event) => {
        try {
            DataUtilities.changeDataDefinitionTypeByPath(props.data, event.target.value, props.path);
            props.onUpdate();
        }
        catch (e) { }
    };
    return (_jsxs(DataEditorRow, Object.assign({ onMouseOver: () => setShowTools(true), onMouseOut: () => setShowTools(false) }, { children: [_jsx(CollapseDiv, { children: _jsx("div", Object.assign({ className: "div-collapse" }, { children: props.onCollapse && (_jsx(IconButton, Object.assign({ onClick: props.onCollapse, size: "small" }, { children: props.viewDetails ? _jsx(ArrowDropUpOutlinedIcon, {}, void 0) : _jsx(ArrowDropDownOutlinedIcon, {}, void 0) }), void 0)) }), void 0) }, void 0),
            _jsxs(DataEditorDefDiv, { children: [_jsxs(FieldNameDiv, { children: [_jsx(TextField, { value: fieldName, variant: "outlined", onChange: (event) => {
                                    setFieldName(event.target.value);
                                }, onBlur: onUpdateFieldName, onKeyUp: (event) => {
                                    if (event.key === "Enter") {
                                        onUpdateFieldName();
                                    }
                                }, classes: { root: "DefEditor-text" }, error: !!error, helperText: error, "data-testid": `${props.path}-name`, id: `${props.path}-name`, className: "field-name", inputProps: { readOnly: props.readOnly } }, void 0),
                            _jsx("div", { id: `${props.path}-name-connector`, className: "path-connector" }, void 0)] }, void 0),
                    !props.readOnly && (_jsxs(_Fragment, { children: [_jsx(Select, Object.assign({ variant: "outlined", native: true, value: field.type, "data-testid": `${props.path}-type`, classes: { root: "DefEditor-select" }, onChange: onUpdateChangeType }, { children: Object.values(XDataType).map((item, index) => {
                                    return (_jsx("option", Object.assign({ value: item }, { children: item }), index));
                                }) }), void 0),
                            _jsx(FormControlLabel, { label: "Is List", "data-testid": `${props.path}-list`, classes: { root: "DefEditor-checkboxLabel" }, control: _jsx(Checkbox, { color: "primary", checked: !!field.list, onChange: (_, checked) => {
                                        field.list = checked;
                                        if (checked) {
                                            DataUtilities.set(props.data.getValueObject(), props.path, [], false, true);
                                        }
                                        else {
                                            DataUtilities.set(props.data.getValueObject(), props.path, undefined, false, true);
                                        }
                                        props.onUpdate();
                                    } }, void 0) }, void 0)] }, void 0)),
                    props.readOnly && (_jsxs(_Fragment, { children: [_jsx("div", Object.assign({ className: "data-field-type" }, { children: _jsx("span", { children: field.type }, void 0) }), void 0),
                            _jsx(FormLabel, Object.assign({ component: "label", className: "data-field-list" }, { children: field.list ? "List" : "Not List" }), void 0)] }, void 0)),
                    !props.readOnly && (_jsx(LineButtons, { onUpdate: props.onUpdate, data: props.data, path: props.path, index: props.index, isLast: props.isLast, show: showTools, field: props.field }, void 0))] }, void 0)] }), void 0));
};
export const FieldEditor = (props) => {
    let field = props.field;
    let subfields = Reflect.get(field, "fields");
    let path = props.path;
    let parent = false;
    if (!path.includes(".")) {
        parent = true;
    }
    const [viewDetails, setViewDetails] = useState(true);
    const onCollapse = () => {
        setViewDetails(!viewDetails);
    };
    if (subfields) {
        return (_jsxs("div", Object.assign({ className: parent ? "field-parent-editor" : "" }, { children: [_jsx(FieldControl, { field: field, path: props.path, data: props.data, onUpdate: props.onUpdate, viewDetails: viewDetails, index: props.index, isLast: props.isLast, onCollapse: onCollapse, readOnly: props.readOnly }, void 0),
                props.parentId !== "" && (_jsx(Xarrow, { end: `${props.parentId}-name-connector`, start: `${props.path}-name`, startAnchor: "left", endAnchor: "bottom", path: "grid", showHead: false, showTail: false, color: "#d3d6e7", strokeWidth: 1 }, void 0)),
                _jsx(Collapse, Object.assign({ in: viewDetails }, { children: _jsx(SubFieldsEditor, { data: props.data, path: props.path, fields: subfields, onUpdate: props.onUpdate, readOnly: props.readOnly, parentId: `${props.path}-name` }, void 0) }), void 0)] }), void 0));
    }
    return (_jsxs("div", Object.assign({ className: parent ? "field-parent-editor" : "" }, { children: [_jsx(FieldControl, { data: props.data, onUpdate: props.onUpdate, field: field, path: props.path, index: props.index, isLast: props.isLast, showValueControl: true, readOnly: props.readOnly }, void 0),
            props.parentId !== "" && (_jsx(Xarrow, { end: `${props.parentId}-name-connector`, start: `${props.path}-name`, startAnchor: "left", path: "grid", showHead: false, showTail: false, endAnchor: "bottom", color: "#d3d6e7", strokeWidth: 1 }, void 0))] }), void 0));
};
const ValueEditorDiv = styled.div `
    display: flex;
    justify-content: flex-start;
    width: 100%;
    align-items: center;
    flex-direction: row;
    ${(props) => !props.notHostEditLayer &&
    `
    position: relative;
  `};
    ${(props) => !props.noBorder &&
    `
    border-bottom: solid 1px #c4c4c4;
  `};

    height: 52px;
    ${(props) => !props.noSetMinHeight &&
    `
  `};
    .input-value-field {
        width: 400px;
    }
    .input-value-field input {
        background: #fcfcfe;
    }
`;
const ValueEditorValueDiv = styled.div `
    width: 100%;
    padding: 0 5px;
    display: flex;
    align-items: center;
    ${(props) => !props.noSetMinHeight && `min-height: 52px;`};

    ${(props) => !props.showLabel &&
    `
        .MuiOutlinedInput-inputMarginDense {
            padding-top: 10px;
        }
    `}

    .MuiTypography-body1 {
        line-height: 29px;
    }
`;
export const ValueEditor = (props) => {
    const [value, setValue] = useState(props.value);
    const onValueUpdate = (newValue) => {
        setValue(newValue);
        console.log(props.field.name, newValue);
        props.onUpdate(newValue);
    };
    let subfields = Reflect.get(props.field, "fields");
    if (subfields) {
        return (_jsxs(_Fragment, { children: [_jsx(ValueEditorDiv, { children: _jsx(XValueEditor, { forData: props.field, value: value, onUpdate: onValueUpdate, mode: "edit_mode", editMode: "layer" }, void 0) }, void 0),
                props.field.list ? (_jsx(ValuesTable, { field: props.field, data: props.data, path: props.path, onUpdate: onValueUpdate, readOnly: props.readOnly, value: value }, void 0)) : (_jsx(SubValues, { fields: subfields, data: props.data, onUpdate: onValueUpdate, path: props.path, readOnly: props.readOnly, value: value }, void 0))] }, void 0));
    }
    return (_jsx(ValueEditorDiv, Object.assign({ noBorder: props.noBorder, noSetMinHeight: props.noSetMinHeight, notHostEditLayer: props.notHostEditLayer }, { children: _jsx(ValueEditorValueDiv, Object.assign({ noSetMinHeight: props.noSetMinHeight, showLabel: props.showLabel }, { children: _jsx(XValueEditor, { forData: props.field, value: value, onUpdate: onValueUpdate, mode: props.field.list ? "display_mode_edit" : "edit_mode", editMode: "layer" }, void 0) }), void 0) }), void 0));
};
const LineButtonsDiv = styled.div `
    position: absolute;
    top: -15px;
    right: 0;
    z-index: 10;
`;
export const LineButtons = (props) => {
    const [anchorEl, setAnchorEl] = useState(null);
    const changePosition = (newindex) => {
        if (newindex < 0)
            return;
        DataUtilities.changeFieldPositionByPath(props.data, newindex, props.path);
        props.onUpdate();
    };
    const removeField = (event) => {
        event.stopPropagation();
        /* eslint-disable no-debugger */
        DataUtilities.removeFieldByPath(props.data, props.path);
        props.onUpdate();
    };
    return (_jsx(Fade, Object.assign({ in: props.show }, { children: _jsx(LineButtonsDiv, { children: _jsxs(ButtonGroup, Object.assign({ variant: "contained" }, { children: [props.index > 0 && (_jsx(Button, Object.assign({ size: "small", onClick: () => changePosition(props.index - 1), "data-testid": `${props.path}-move-up` }, { children: _jsx(ArrowUpwardOutlined, { fontSize: "small" }, void 0) }), void 0)),
                    !props.isLast && (_jsx(Button, Object.assign({ size: "small", onClick: () => changePosition(props.index + 1), "data-testid": `${props.path}-move-down` }, { children: _jsx(ArrowDownwardOutlined, { fontSize: "small" }, void 0) }), void 0)),
                    _jsx(Button, Object.assign({ size: "small", "aria-label": "delete", onClick: removeField, "data-testid": `${props.path}-remove` }, { children: _jsx(DeleteOutlined, { fontSize: "small" }, void 0) }), void 0),
                    props.field.type !== XDataType.BOOLEAN && (_jsxs(Button, Object.assign({ size: "small", "aria-label": "edit", "data-testid": `${props.path}-edit`, onClick: (event) => {
                            setAnchorEl(event.currentTarget);
                        } }, { children: [_jsx(Pencil, { fontSize: "small" }, void 0),
                            _jsx(DataDefEditLayer, { dataDef: props.field, onUpdate: () => {
                                    props.onUpdate();
                                }, anchorEl: anchorEl, open: Boolean(anchorEl), keepMounted: true, onClose: () => {
                                    setAnchorEl(null);
                                } }, void 0)] }), void 0))] }), void 0) }, void 0) }), void 0));
};
const EditJsonDiv = styled.div `
    .MuiInputBase-multiline {
        background: #1b1b1b;
        font-family: MyFancyCustomFont, monospace;
        font-size: inherit;
        color: #f5d67b;
    }
`;
export const EditModal = (props) => {
    const [value, setValue] = useState(props.value);
    const onChange = (event) => {
        setValue(event.target.value);
    };
    return (_jsxs(Dialog, Object.assign({ open: props.open, onClose: props.onClose, "aria-labelledby": "datadefinition-editor-json-modal", maxWidth: "lg", fullWidth: true }, { children: [_jsx(DialogTitle, Object.assign({ id: "datadefinition-editor-json-modal" }, { children: "Edit JSON" }), void 0),
            _jsx(DialogContent, { children: _jsx(EditJsonDiv, { children: _jsx(TextField, { rows: 10, multiline: true, value: value, onChange: onChange, variant: "outlined", fullWidth: true }, void 0) }, void 0) }, void 0),
            _jsxs(DialogActions, { children: [_jsx(Button, Object.assign({ onClick: props.onClose, color: "primary" }, { children: "Cancel" }), void 0),
                    _jsx(Button, Object.assign({ onClick: () => props.onEdit(value), color: "primary" }, { children: "Update" }), void 0)] }, void 0)] }), void 0));
};
export const DataChangesModal = (props) => {
    const [changes, setChanges] = useState(props.data);
    const [selectedChanges, setSelectedChanges] = useState({});
    const onChange = (event) => {
        setSelectedChanges(Object.assign(Object.assign({}, selectedChanges), { [event.target.name]: event.target.checked }));
    };
    return (_jsxs(Dialog, Object.assign({ open: props.open, onClose: props.onClose, "aria-labelledby": "datadefinition-editor-structure-changes-modal", maxWidth: "sm", fullWidth: true }, { children: [_jsx(DialogTitle, Object.assign({ id: "datadefinition-editor-structure-changes-modal" }, { children: "Changes you made" }), void 0),
            _jsx(DialogContent, { children: _jsx(FormControl, Object.assign({ component: "fieldset" }, { children: _jsx(FormGroup, { children: changes.map((change) => {
                            return (_jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: selectedChanges[change.field.name], onChange: (e) => onChange(e), name: change.field.name }, void 0), label: change.getMessage() }, void 0));
                        }) }, void 0) }), void 0) }, void 0),
            _jsxs(DialogActions, { children: [_jsx(Button, Object.assign({ onClick: props.onClose, color: "primary" }, { children: "Cancel" }), void 0),
                    _jsx(Button, Object.assign({ onClick: () => props.onUpdate(selectedChanges), color: "primary" }, { children: "Update" }), void 0)] }, void 0)] }), void 0));
};
//# sourceMappingURL=XDefinitionEditor.js.map