"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importStar(require("react"));
const FormHelperText_1 = tslib_1.__importDefault(require("@material-ui/core/FormHelperText"));
const List_1 = tslib_1.__importDefault(require("@material-ui/core/List"));
const ListItem_1 = tslib_1.__importDefault(require("@material-ui/core/ListItem"));
const TextField_1 = tslib_1.__importDefault(require("@material-ui/core/TextField"));
const core_1 = require("@material-ui/core");
const styled_components_1 = tslib_1.__importDefault(require("styled-components"));
const DataUtilities_1 = require("@appglue/common/dist/Common/DataUtilities");
const DataTypes_1 = require("@appglue/common/dist/Common/Data/DataTypes");
const DropdownIcon_1 = require("./Icon/DropdownIcon");
const ObjectDataDefinition_1 = require("@appglue/common/dist/Common/Data/Definitions/ObjectDataDefinition");
const SearchGrayIcon_1 = require("./Icon/SearchGrayIcon");
const StyledButton_1 = require("./BuildlingBlocks/StyledButton");
const UIStyleConstants_1 = require("@appglue/common/dist/Common/UIStyleConstants");
function checkIfTypeMatched(data, path, requiredType, isList, selectedField) {
    if (!requiredType)
        return true;
    if (!selectedField) {
        selectedField = DataUtilities_1.DataUtilities.getFieldFromDataDefinitionByName(data.fields, path);
    }
    if (requiredType instanceof ObjectDataDefinition_1.ObjectDataDefinition &&
        !DataUtilities_1.DataUtilities.compareStructureToPath(requiredType, data, path)) {
        return false;
    }
    else if (requiredType &&
        !(requiredType instanceof ObjectDataDefinition_1.ObjectDataDefinition) &&
        (selectedField.type !== requiredType || ((isList || selectedField.list) && isList !== selectedField.list))) {
        return false;
    }
    else if (!requiredType && (isList || selectedField.list) && isList !== selectedField.list) {
        return false;
    }
    return true;
}
const VariablePicker = (props) => {
    const [showContent, setShowContent] = (0, react_1.useState)(props.open || false);
    const [selected, setSelected] = (0, react_1.useState)(props.selected);
    const [searchStr, setSearchStr] = (0, react_1.useState)("");
    const [mode, setMode] = (0, react_1.useState)(props.data.fields.length === 0 && props.allowNewVariable ? "new" : "pick");
    const [value, setValue] = (0, react_1.useState)(null);
    let selectedField = (0, react_1.useMemo)(() => {
        try {
            return DataUtilities_1.DataUtilities.getFieldFromDataDefinitionByName(props.data.fields, selected);
        }
        catch (e) {
            return undefined;
        }
    }, [props.data.fields, selected]);
    (0, react_1.useEffect)(() => {
        setShowContent(props.open || false);
    }, [props.open]);
    const ref = react_1.default.useRef(null);
    let show = showContent;
    const [newVariable, setNewVariable] = (0, react_1.useState)(() => {
        let state = {
            name: "",
            type: DataTypes_1.DataTypes.STRING,
            path: "",
            islist: props.isList || false,
        };
        if (!selectedField) {
            if (props.selected) {
                state.name = props.selected;
            }
            if (props.requiredType && !(props.requiredType instanceof ObjectDataDefinition_1.ObjectDataDefinition)) {
                state.type = props.requiredType;
            }
        }
        return state;
    });
    const error = (0, react_1.useMemo)(() => {
        if (props.errors && props.errors.length) {
            return props.errors[0].issue;
        }
        else if (selectedField) {
            if (checkIfTypeMatched(props.data, selected, props.requiredType, props.isList, selectedField))
                return;
            return "Incorrect variable type";
        }
        else if (selected && !selectedField) {
            return "Selected field does not exists in fields.";
        }
        return;
    }, [selectedField, selected, props.requiredType, props.errors]);
    const filteredFields = DataUtilities_1.DataUtilities.filterFieldsByName(props.data.fields, value || searchStr);
    (0, react_1.useEffect)(() => {
        setSelected(props.selected);
    }, [props.selected, setSelected]);
    const onClose = () => {
        if (props.onClose) {
            props.onClose();
        }
        else {
            setShowContent(false);
        }
    };
    const onChange = (event) => {
        setValue(event.target.value);
        setNewVariable({
            ...newVariable,
            name: event.target.value,
        });
    };
    const onSelect = (path) => {
        setValue(null);
        setSelected(path);
    };
    const onChangeNewVariableName = (event) => {
        setNewVariable({
            ...newVariable,
            name: event.target.value,
        });
    };
    const onChangeNewValueIsList = (event) => {
        setNewVariable({
            ...newVariable,
            islist: event.target.checked,
        });
    };
    const onChangeNewVariableType = (event) => {
        setNewVariable({
            ...newVariable,
            type: event.target.value,
        });
    };
    const onAddNew = () => {
        if (newVariable && newVariable.name.trim() !== "" && props.allowNewVariable) {
            let def = null;
            if (typeof props.requiredType === "object") {
                const type = Reflect.get(props.requiredType, "type");
                def = DataUtilities_1.DataUtilities.createDataByType(type);
                DataUtilities_1.DataUtilities.spreadDeepData(def, props.requiredType);
            }
            else if (props.requiredType) {
                def = DataUtilities_1.DataUtilities.createDataByType(props.requiredType);
            }
            else {
                def = DataUtilities_1.DataUtilities.createDataByType(newVariable.type);
            }
            def.name = newVariable.name;
            def.list = newVariable.islist;
            setValue(null);
            setNewVariable({
                name: "",
                type: DataTypes_1.DataTypes.STRING,
                path: "",
                islist: false,
            });
            setMode("pick");
            onClose();
            props.onVariableSet(newVariable.path, def);
        }
    };
    const renderListFields = (fields, keys = []) => {
        return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(List_1.default, { children: fields.map((f) => {
                    const path = [...keys, f.name || ""].join(".");
                    const available = checkIfTypeMatched(props.data, path, props.requiredType, props.isList);
                    if (f.type === DataTypes_1.DataTypes.OBJECT) {
                        const subfields = Reflect.get(f, "fields");
                        return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsx)(ListItem_1.default, { button: true, onClick: (event) => {
                                        event.stopPropagation();
                                        onSelect(path);
                                    }, selected: selected === path, "data-testid": `${path}${selected === path ? "-selected" : ""}`, color: "primary", children: (0, jsx_runtime_1.jsx)(core_1.ListItemText, { primary: f.name, primaryTypographyProps: {
                                            classes: {
                                                root: available ? "available" : undefined,
                                            },
                                        } }) }), (0, jsx_runtime_1.jsx)(NestedListWrapper, { children: subfields.length ? renderListFields(subfields, [...keys, f.name || ""]) : null })] }, path));
                    }
                    else {
                        return ((0, jsx_runtime_1.jsxs)(ListItem_1.default, { selected: selectedField === f, button: true, color: "primary", onClick: (event) => {
                                event.stopPropagation();
                                onSelect(path);
                            }, "data-testid": `${path}${selectedField === f ? "-selected" : ""}`, children: [(0, jsx_runtime_1.jsx)(core_1.ListItemText, { primary: f.name, primaryTypographyProps: {
                                        classes: {
                                            root: available ? "available" : undefined,
                                        },
                                    } }), (0, jsx_runtime_1.jsx)(core_1.ListItemText, { secondary: f.type })] }, `${path}`));
                    }
                }) }) }));
    };
    const renderExistingFields = () => {
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Subheader, { children: (0, jsx_runtime_1.jsx)(TextField_1.default, { value: searchStr, onChange: (event) => setSearchStr(event.target.value || ""), placeholder: "Search", "data-testid": "variable-picker-search", fullWidth: true, classes: {
                            root: "Search_TextField",
                        }, InputProps: {
                            endAdornment: (0, jsx_runtime_1.jsx)(SearchGrayIcon_1.SearchGrayIcon, {}),
                        } }) }), (0, jsx_runtime_1.jsxs)(ExistingWrapper, { children: [renderListFields(filteredFields, []), filteredFields.length === 0 && ((0, jsx_runtime_1.jsx)(FormHelperText_1.default, { classes: { root: "VariablePicker-nofieldMessage" }, children: "There is no fields." })), props.allowNewVariable && ((0, jsx_runtime_1.jsx)(ButtonGroupDiv, { marginTop: 8, children: (0, jsx_runtime_1.jsx)(core_1.Link, { classes: {
                                    root: "BtnVariablePicker-to-create",
                                }, "data-testid": "VariablePicker_NewMode", onClick: (event) => {
                                    event.stopPropagation();
                                    setMode("new");
                                }, children: "Add new" }) }))] })] }));
    };
    const renderButtons = (mode, sticky) => {
        if (mode === "new")
            return ((0, jsx_runtime_1.jsxs)(ButtonGroupDiv, { marginTop: 8, className: "VariablePicker-buttonGroups", sticky: sticky, children: [(0, jsx_runtime_1.jsx)(core_1.Link, { onClick: (event) => {
                            event.stopPropagation();
                            if (props.data.fields.length > 0) {
                                setMode("pick");
                            }
                            else {
                                onClose();
                                props.onVariableSet("");
                            }
                        }, children: "Cancel" }), (0, jsx_runtime_1.jsx)(StyledButton_1.StyledButton, { variant: "contained", color: "primary", onClick: (event) => {
                            event.stopPropagation();
                            onAddNew();
                        }, "data-testid": "BtnCreateVariable", children: "Create" })] }));
        return ((0, jsx_runtime_1.jsxs)(ButtonGroupDiv, { marginTop: 8, sticky: sticky, className: "VariablePicker-buttonGroups", children: [(0, jsx_runtime_1.jsx)(core_1.Link, { onClick: (event) => {
                        event.stopPropagation();
                        props.onVariableSet(props.selected || "");
                        setSelected(props.selected);
                        onClose();
                    }, children: "Cancel" }), (0, jsx_runtime_1.jsx)(StyledButton_1.StyledButton, { "data-testid": "VariablePicker_Select", variant: "contained", color: "primary", disabled: !selected || selected === "", onClick: (event) => {
                        event.stopPropagation();
                        props.onVariableSet(selected || "");
                        onClose();
                    }, children: "Choose" })] }));
    };
    const renderNewField = () => ((0, jsx_runtime_1.jsxs)(NewFieldDiv, { children: [(0, jsx_runtime_1.jsxs)(FormControl, { children: [(0, jsx_runtime_1.jsx)(StyledInputLabel, { children: "Data Name" }), (0, jsx_runtime_1.jsx)(TextField_1.default, { variant: "outlined", value: newVariable.name, onChange: onChangeNewVariableName, error: newVariable.name === "", helperText: newVariable.name === "" ? "name is required" : "", "data-testid": "variable-picker-add", onKeyUp: (event) => {
                            if (event.key === "Enter") {
                                onAddNew();
                            }
                        } })] }), (0, jsx_runtime_1.jsxs)(FormControl, { children: [(0, jsx_runtime_1.jsx)(StyledInputLabel, { children: "Type" }), (0, jsx_runtime_1.jsxs)(TextField_1.default, { select: true, variant: "outlined", SelectProps: { native: true, disabled: !!props.requiredType }, value: newVariable.type, onChange: onChangeNewVariableType, "data-testid": "variable-picker-change-type", children: [(0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.STRING }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.NUMBER }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.BOOLEAN }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.DATE }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.FILE }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.OBJECT }), (0, jsx_runtime_1.jsx)("option", { children: DataTypes_1.DataTypes.UNDEFINED })] })] }), (0, jsx_runtime_1.jsx)(FormControl, { children: (0, jsx_runtime_1.jsx)(core_1.FormControlLabel, { "data-testid": "variable-picker-is-list", control: (0, jsx_runtime_1.jsx)(core_1.Checkbox, { checked: newVariable.islist, onChange: onChangeNewValueIsList, name: "islist", color: "primary" }), label: "is list" }) })] }));
    return ((0, jsx_runtime_1.jsxs)(VariablePickerDiv, { className: "VariablePicker_root", fullWidth: props.inputProps?.fullWidth, inputSize: props.inputProps?.size || "medium", ref: ref, "data-testid": "VariablePicker_root", children: [!props.hideInput && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [props.renderInput ? (props.renderInput()) : ((0, jsx_runtime_1.jsx)(TextField_1.default, { classes: {
                            root: "VariablePicker_TextField",
                        }, value: value || selected, onChange: onChange, onFocus: () => {
                            setShowContent(true);
                        }, variant: props.inputProps?.variant || "outlined", error: !!error, helperText: error, "data-testid": `variable-picker-value${props.requiredType && error ? "-error" : ""}`, InputProps: {
                            endAdornment: ((0, jsx_runtime_1.jsx)(core_1.InputAdornment, { position: "end", onClick: () => setShowContent(true), children: (0, jsx_runtime_1.jsx)(DropdownIcon_1.DropdownIcon, {}) })),
                            readOnly: !props.allowNewVariable && props.data.fields.length === 0,
                        }, label: props.label, InputLabelProps: { shrink: true }, fullWidth: props.inputProps?.fullWidth, autoFocus: !!props.startOpenIfEmptyOrInvalid && !selectedField, inputProps: {
                            style: props.inputProps?.style,
                        } })), (props.isList === true || typeof props.requiredType !== "undefined") && ((0, jsx_runtime_1.jsxs)(ExpectedTypeWrapper, { className: "expected-type-render", alwaysShow: !!error, "data-testid": `expected-type-render-${props.requiredType}`, children: ["Expected Type:", " ", (0, jsx_runtime_1.jsxs)("span", { className: "type", children: [props.requiredType
                                        ? typeof props.requiredType === "string"
                                            ? props.requiredType
                                            : "object data definition"
                                        : "", props.isList ? " list" : ""] })] }))] })), props.notPopup ? ((0, jsx_runtime_1.jsxs)(VariablePickerContentDiv, { className: "VariablePicker_Content", children: [props.renderTitle && props.renderTitle(), mode === "new" ? renderNewField() : renderExistingFields(), renderButtons(mode)] })) : ((0, jsx_runtime_1.jsxs)(StyledMenu, { open: show, anchorEl: props.anchorEl || ref.current, disableEnforceFocus: true, disableRestoreFocus: true, onClose: () => {
                    if (props.selected !== selected && selected) {
                        props.onVariableSet(selected);
                    }
                    onClose();
                }, getContentAnchorEl: null, children: [(0, jsx_runtime_1.jsxs)(VariablePickerContentDiv, { className: "VariablePicker_Content", children: [props.renderTitle && props.renderTitle(), mode === "new" ? renderNewField() : renderExistingFields()] }), renderButtons(mode, true)] }))] }));
};
exports.default = VariablePicker;
const VariablePickerDiv = styled_components_1.default.div `
    position: relative;
    display: inline-block;
    width: ${(props) => (props.fullWidth ? "100%" : "auto")};

    &:hover .expected-type-render {
        opacity: 1;
    }

    .MuiInputBase-root {
        font-size: 12px;
        font-style: normal;
        font-weight: 500;
        line-height: 20px;
        letter-spacing: 0em;
        text-align: left;
    }

    .MuiOutlinedInput-input {
        padding: 6px 12px;
        font-size: 14px;
        font-style: normal;
        font-weight: 400;
        height: auto;
        background: #fcfcfe;
    }

    .VariablePicker_TextField .MuiOutlinedInput-input {
        ${(props) => (props.inputSize === "large" ? "padding: 10px 12px;" : "")}
        ${(props) => (props.inputSize === "medium" ? "padding: 8px 12px;" : "")}
    ${(props) => (props.inputSize === "small" ? "padding: 6px 12px;" : "")}
    }

    .VariablePicker_TextField .MuiFormHelperText-root.Mui-error {
        line-height: 1;
        margin-top: 5px;
    }

    .MuiOutlinedInput-notchedOutline {
        border: 1px solid rgba(39, 41, 50, 0.2);
        border-radius: 4px;
    }

    .MuiList-root {
        &.MuiList-padding {
            padding-top: 0;
            padding-bottom: 0;
        }

        .MuiListItem-root {
            padding: 5px 12px;
            display: flex;
            justify-content: space-between;
        }

        .MuiListSubheader-gutters {
            padding: 0 12px;
        }

        .MuiListItemText-root {
            flex: inherit;
            margin: 0;

            .MuiTypography-body1 {
                font-size: 12px;
                font-style: normal;
                font-weight: 400;
                line-height: 17px;
                letter-spacing: 0px;
                text-align: left;
            }

            .MuiListItemText-primary {
                color: #27293299;
                font-weight: 300;

                &.available {
                    color: #272932;
                    font-weight: 700;
                }
            }

            .MuiListItemText-secondary {
                color: rgba(64, 80, 166, 0.8);
                text-transform: capitalize;
            }
        }
    }
`;
const VariablePickerContentDiv = styled_components_1.default.div `
    padding: 0 10px;

    width: 300px;

    max-width: 100%;

    background: white;

    display: flex;
    flex-direction: column;

    .MuiInputBase-root {
        font-size: 12px;
        font-style: normal;
        font-weight: 500;
        line-height: 20px;
        letter-spacing: 0em;
        text-align: left;
    }

    .MuiOutlinedInput-input {
        padding: 6px 12px;
        font-size: 14px;
        font-style: normal;
        font-weight: 400;
        height: auto;
        background: #fcfcfe;
    }

    .MuiOutlinedInput-notchedOutline {
        border: 1px solid rgba(39, 41, 50, 0.2);
        border-radius: 4px;
    }

    .MuiList-root {
        &.MuiList-padding {
            padding-top: 0;
            padding-bottom: 0;
        }

        .MuiListItem-root {
            padding: 5px 12px;
            display: flex;
            justify-content: space-between;

            &.Mui-selected {
                background: rgba(64, 80, 166, 0.4);
            }
        }

        .MuiListSubheader-gutters {
            padding: 0 12px;
            background: ${UIStyleConstants_1.UIStyleConstants.WHITE_COLOR};
        }

        .MuiListItemText-root {
            flex: inherit;
            margin: 0;

            .MuiTypography-body1 {
                font-size: 12px;
                font-style: normal;
                font-weight: 400;
                line-height: 17px;
                letter-spacing: 0px;
                text-align: left;
            }

            .MuiListItemText-primary {
                color: #27293299;
                font-weight: 300;

                &.available {
                    color: #272932;
                    font-weight: 700;
                }
            }

            .MuiListItemText-secondary {
                color: rgba(64, 80, 166, 0.8);
                text-transform: capitalize;
            }
        }
    }
`;
const NestedListWrapper = styled_components_1.default.div `
    padding-left: 10px;
`;
const NewFieldDiv = styled_components_1.default.div `
    padding-top: 13px;
    display: flex;
    flex-direction: column;
`;
const StyledInputLabel = styled_components_1.default.label `
    display: flex;

    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: 17px;
    letter-spacing: 0px;
    text-align: left;
    color: #272932;

    margin-bottom: 4px;
`;
const FormControl = styled_components_1.default.div `
    display: flex;
    flex-direction: column;
    margin-bottom: 11px;
`;
const ExistingWrapper = styled_components_1.default.div `
    display: flex;
    flex-direction: column;
    overflow: hidden;

    .MuiList-root {
        flex: 1;

        overflow-y: auto;
        overflow-x: hidden;
    }

    .Search_TextField {
        padding: 7px 0 3px;

        .MuiOutlinedInput-input {
            padding: 5px 10px;
        }

        .MuiInputBase-input {
            font-size: 14px;
            font-style: normal;
            font-weight: 400;
            line-height: 20px;
            letter-spacing: 0em;
            text-align: left;
        }
    }

    .VariablePicker-nofieldMessage {
        padding: 0 12px;
    }
`;
const ButtonGroupDiv = styled_components_1.default.div `
    display: flex;
    align-items: center;
    justify-content: right;

    ${(props) => props.sticky &&
    `
            position: sticky;
            bottom: 0px;
            background: ${UIStyleConstants_1.UIStyleConstants.WHITE_COLOR};
            padding: 8px 12px;
            
    `}
    ${(props) => (props.marginTop ? `margin-top: ${props.marginTop}px;` : "")}
  .BtnVariablePicker-to-create {
        margin-left: auto;
    }

    .MuiLink-root {
        text-align: center;
    }

    > * {
        margin-left: 10px !important;
    }
`;
const Subheader = styled_components_1.default.div `
    padding: 13px 8px 5px;
    position: sticky;
    top: 0;

    background: ${UIStyleConstants_1.UIStyleConstants.WHITE_COLOR};

    z-index: 2;
`;
const StyledMenu = (0, styled_components_1.default)(core_1.Menu) `
    .MuiList-root[role="menu"] {
        padding: 0;
    }
`;
const ExpectedTypeWrapper = styled_components_1.default.div `
    color: rgba(39, 41, 50, 0.5);
    font-size: 12px;
    margin-left: 14px;
    margin-right: 14px;
    margin-top: 5px;
    line-height: 1;

    ${(props) => !props.alwaysShow &&
    `
            opacity: 0;
        `}
    .type {
        font-weight: 700;
        color: rgba(64, 80, 166, 1);
    }
`;
//# sourceMappingURL=VariablePicker.js.map