import { __decorate, __metadata } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from "react";
import { Tab } from "@material-ui/core";
import styled from "styled-components";
import { XFormDataEditing } from "./Components/XFormDataEditing";
import { FormDesignConstants, FormMode } from "./FormDesignConstants";
import { XFormAndLayoutDesignPanel } from "./Utilities/XFormAndLayoutDesignPanel";
import { Topbar, IInjectTopItemType } from "../CommonUI/BuildUI/Topbar";
import { AutoBind } from "../Common/AutoBind";
import { FormContext } from "./Utilities/FormContext";
import { UserFormData } from "./UserFormData";
import { XUserFormTester } from "./Utilities/XUserFormTester";
import { XDefinitionEditor } from "../CommonUI/DataDesigner/XDefinitionEditor";
import { RulesIcon } from "../CommonUI/Icon/RulesIcon";
import { TabletHorizontalIcon } from "../CommonUI/Icon/TabletHorizontalIcon";
import { TabletVerticalIcon } from "../CommonUI/Icon/TabletVerticalIcon";
import { CellphoneHorizontalIcon } from "../CommonUI/Icon/CellphoneHorizontalIcon";
import { CellphoneVerticalIcon } from "../CommonUI/Icon/CellphoneVerticalIcon";
import { PaperIcon } from "../CommonUI/Icon/PaperIcon";
import { BrushIcon } from "../CommonUI/Icon/BrushIcon";
import { OutlineIcon } from "../CommonUI/Icon/OutlineIcon";
import { NoneIcon } from "../CommonUI/Icon/NoneIcon";
import { Sidebar } from "../CommonUI/BuildUI/Sidebar";
import { RegisterFormElements } from "./registerElements";
import { DataGrayIcon } from "../CommonUI/Icon/DataGrayIcon";
import { ConsentIcon } from "../CommonUI/Icon/ConsentIcon";
import { RuleTableIcon } from "../CommonUI/Icon/RuleTableIcon";
import { TestDataIcon } from "../CommonUI/Icon/TestDataIcon";
import { CodingIcon } from "../CommonUI/Icon/CodingIcon";
import { XFormRulePage } from "./Components/XFormRulePage";
import "./XFormDesigner.css";
export const StyledTab = styled(Tab) `
    && {
        min-width: 50px;
        width: 50px;
        height: 50px;

        color: #01244e;
        border-top: 1px solid #e6e9ed;
        border-bottom: 1px solid #e6e9ed;
        border-left: 3px solid transparent;
        text-transform: capitalize;
        font-family: Mulish;
        font-weight: 600;
        text-align: center;

        &.SidebarTab-selected {
            color: #15466b;
            border-left: 3px solid #15466b;
            background-color: #dceaf5;
        }

        @media (min-width: 1366px) {
            min-width: calc(96px + 7 * (100vw - 1366px) / 554);
            width: calc(96px + 7 * (100vw - 1366px) / 554);
            height: auto;
            padding: calc(18px + 3 * (100vw - 1366px) / 554) 0;
            font-size: 13px;
            line-height: 16px;
        }

        @media (min-width: 1920px) {
            min-width: 103px;
            width: 103px;
            padding: 21px 0;
            font-size: 14px;
            line-height: 18px;
        }

        .SidebarTabWrapper {
            display: flex;
            flex-flow: column;
            align-items: center;

            img {
                margin-bottom: 0px;
                width: 21px;
                @media (min-width: 1366px) {
                    margin-bottom: 9px;
                }
            }

            span {
                display: none;

                @media (min-width: 1366px) {
                    display: inline;
                }
            }
        }
    }
`;
export class XFormDesigner extends React.Component {
    constructor(props) {
        super(props);
        this.formName = "";
        this.tabs = [];
        this.designConfig = this.getDefaultDesignConfig();
        this.runtimeConfig = this.getDefaultRuntimeConfig();
        this.onJsonEditing = (isJsonEditing) => {
            this.setState({
                isJsonEditing,
            });
        };
        this.onNextMode = (isLeaving) => {
            if (isLeaving) {
                this.editContext.mode = this.state.nextMode;
                this.setState({
                    mode: this.state.nextMode,
                });
            }
            else {
                this.setState({
                    nextMode: this.state.mode,
                });
            }
        };
        // ensure controls are registered.
        RegisterFormElements.doRegistration();
        this.editContext = this.setupProps(props);
        this.state = {
            mode: FormMode.FormDesign,
            isJsonEditing: false,
            nextMode: FormMode.FormDesign,
        };
        if (props.dataDefinition) {
            props.form.inputData = props.dataDefinition;
        }
    }
    componentDidUpdate(prevProps) {
        var _a;
        if (this.props.form !== prevProps.form) {
            this.editContext = this.setupProps(this.props);
            this.setState({
                mode: FormMode.FormDesign,
                isJsonEditing: false,
                nextMode: FormMode.FormDesign,
            });
        }
        else {
            if (this.props.formData !== prevProps.formData) {
                this.editContext.setFormData(this.props.formData ? this.props.formData : new UserFormData());
            }
            if (this.props.formName !== prevProps.formName)
                this.editContext.formName = this.props.formName;
            if (this.props.designValidationProvider !== prevProps.designValidationProvider)
                this.editContext.designValidationProvider = this.props.designValidationProvider;
            if (this.props.onFormClose !== prevProps.onFormClose)
                this.editContext.onFormClose = this.props.onFormClose;
            if (this.props.onFormSave !== prevProps.onFormSave)
                this.editContext.onFormSave = this.props.onFormSave;
            if (this.props.sampleDataProvider !== prevProps.sampleDataProvider)
                this.editContext.sampleDataProvider = this.props.sampleDataProvider;
            if (this.props.topDesignerExtensions !== prevProps.topDesignerExtensions)
                this.editContext.topDesignerExtensions = this.props.topDesignerExtensions;
            if (this.props.bottomDesignerExtensions !== prevProps.bottomDesignerExtensions)
                this.editContext.bottomDesignerExtensions = this.props.bottomDesignerExtensions;
            if (this.props.designConfig !== prevProps.designConfig)
                this.editContext.designConfig = this.props.designConfig;
            if (((_a = this.editContext.designConfig) === null || _a === void 0 ? void 0 : _a.data) === FormDesignConstants.FORM_DATA_MODE_CURRENT) {
                this.editContext.data = Object.assign(Object.assign({}, this.editContext.getFormData()), this.getDefaultData(this.props.form));
            }
            const { topDesignerExtensions, bottomDesignerExtensions } = this.props;
            if (topDesignerExtensions !== prevProps.topDesignerExtensions ||
                bottomDesignerExtensions !== prevProps.bottomDesignerExtensions) {
                this.tabs = this.getDefaultTabs();
                if (topDesignerExtensions) {
                    this.tabs.splice(0, 0, ...(topDesignerExtensions || []).map((d) => ({
                        icon: d.icon,
                        label: d.name,
                        value: d.name,
                        renderUI: d.renderUI,
                    })));
                }
                if (bottomDesignerExtensions) {
                    this.tabs = [
                        ...this.tabs,
                        ...(bottomDesignerExtensions || []).map((d) => ({
                            icon: d.icon,
                            label: d.name,
                            value: d.name,
                            renderUI: d.renderUI,
                        })),
                    ];
                }
            }
        }
        if (this.props.formName !== prevProps.formName)
            this.formName = this.props.formName || "";
        // set for data definition
        if (this.props.dataDefinition !== prevProps.dataDefinition && this.props.dataDefinition) {
            this.props.form.inputData = this.props.dataDefinition;
        }
    }
    setupProps(props) {
        let eContext = new FormContext(props.form);
        eContext.designer = this;
        if (props.formData)
            eContext.setFormData(props.formData);
        eContext.formName = props.formName;
        eContext.designValidationProvider = props.designValidationProvider;
        eContext.onFormClose = props.onFormClose;
        eContext.onFormSave = props.onFormSave;
        eContext.sampleDataProvider = props.sampleDataProvider;
        eContext.topDesignerExtensions = props.topDesignerExtensions;
        eContext.bottomDesignerExtensions = props.bottomDesignerExtensions;
        eContext.designConfig = props.designConfig || this.getDefaultDesignConfig();
        if (eContext.designConfig.data === FormDesignConstants.FORM_DATA_MODE_CURRENT) {
            const data = this.getDefaultData(props.form);
            eContext.data = data;
        }
        else if (eContext.designConfig.data === FormDesignConstants.FORM_DATA_MODE_NONE) {
            eContext.data = {};
        }
        if (props.initialMode) {
            eContext.mode = props.initialMode;
        }
        this.editContext = eContext;
        this.props.form.setFormContext(eContext);
        if (props.formName) {
            this.formName = props.formName;
        }
        this.tabs = this.getDefaultTabs();
        const { topDesignerExtensions, bottomDesignerExtensions } = props;
        if (topDesignerExtensions) {
            this.tabs.splice(0, 0, ...topDesignerExtensions.map((d) => ({
                icon: d.icon,
                label: d.name,
                value: d.name,
                renderUI: d.renderUI,
            })));
        }
        if (bottomDesignerExtensions) {
            this.tabs = [
                ...this.tabs,
                ...bottomDesignerExtensions.map((d) => ({
                    icon: d.icon,
                    label: d.name,
                    value: d.name,
                    renderUI: d.renderUI,
                })),
            ];
        }
        return eContext;
    }
    getDefaultTabs() {
        return [
            {
                label: "Layout",
                icon: _jsx(RuleTableIcon, {}, void 0),
                value: FormMode.LayoutDesign,
                renderUI: () => _jsx(XFormAndLayoutDesignPanel, { editContext: this.editContext }, void 0),
            },
            {
                label: "Form",
                icon: _jsx(ConsentIcon, {}, void 0),
                value: FormMode.FormDesign,
                renderUI: () => _jsx(XFormAndLayoutDesignPanel, { editContext: this.editContext }, void 0),
            },
            {
                label: "Test Form",
                icon: _jsx(TestDataIcon, {}, void 0),
                value: FormMode.Runtime,
                renderUI: () => _jsx(XUserFormTester, { editContext: this.editContext }, void 0),
            },
            {
                label: "Edit Configuration",
                icon: _jsx(CodingIcon, {}, void 0),
                value: FormMode.JSON,
                renderUI: () => {
                    var _a;
                    return (_jsx(XFormDataEditing, { form: this.props.form, onJSONUpdating: this.onJsonEditing, isLeaving: (((_a = this.state) === null || _a === void 0 ? void 0 : _a.nextMode) || FormMode.FormDesign) !== FormMode.JSON, onNextMode: this.onNextMode }, void 0));
                },
            },
            {
                label: "Data",
                icon: _jsx(DataGrayIcon, {}, void 0),
                value: FormMode.Data,
                renderUI: () => (_jsx(XDefinitionEditor, { definition: this.props.form.getInputDefinition(), readOnly: !this.props.form.canChangeInputs }, void 0)),
            },
            {
                label: "Rules",
                icon: _jsx(RulesIcon, {}, void 0),
                value: FormMode.Rules,
                renderUI: () => _jsx(XFormRulePage, { form: this.props.form }, void 0),
            },
        ];
    }
    // form events.
    onFormSave() {
        // Save Action
        this.props.onFormSave(this.editContext.getFormData());
        // form Name update
        if (this.props.onFormNameUpdate && this.editContext.formName) {
            this.props.onFormNameUpdate(this.editContext.formName);
            this.formName = this.editContext.formName;
        }
    }
    onFormClose() {
        // Cancel Action
        this.props.onFormClose();
        // reset form name on cancel action
        this.formName = this.editContext.formName = this.props.formName || "";
    }
    onCopy() { }
    onCut() { }
    onDelete() { }
    getDefaultDesignConfig() {
        return {
            data: FormDesignConstants.FORM_DATA_MODE_CURRENT,
            mode: FormDesignConstants.FORM_MODE_PAPER,
        };
    }
    getDefaultRuntimeConfig() {
        return {
            data: FormDesignConstants.FORM_DATA_MODE_CURRENT,
            mode: FormDesignConstants.FORM_MODE_PAPER,
        };
    }
    getDefaultData(form) {
        let dataDef = form.inputData;
        if (dataDef) {
            dataDef = typeof dataDef == "function" ? dataDef() : dataDef;
        }
        const data = (dataDef === null || dataDef === void 0 ? void 0 : dataDef.getValueObject()) || {};
        return data;
    }
    handleModeChange(mode) {
        if (this.state.mode === FormMode.Runtime) {
            this.editContext.designConfig = this.runtimeConfig;
        }
        else {
            this.editContext.designConfig = this.designConfig;
        }
        if (this.state.mode !== FormMode.JSON || !this.state.isJsonEditing) {
            this.editContext.mode = mode;
            this.setState({ mode, nextMode: mode });
        }
        else {
            this.setState({ nextMode: mode });
        }
    }
    onChangeSampleData(value) {
        let des = this.editContext.designConfig;
        if (des) {
            des.data = value;
            if (value === FormDesignConstants.FORM_DATA_MODE_NONE) {
                this.editContext.data = {};
            }
            else if (value === FormDesignConstants.FORM_DATA_MODE_CURRENT) {
                const data = this.getDefaultData(this.props.form);
                this.editContext.data = Object.assign({}, data);
            }
            this.forceUpdate();
        }
    }
    onUpdateDisplayMode(value) {
        var _a;
        let des = (_a = this.editContext.designConfig) === null || _a === void 0 ? void 0 : _a.mode;
        if (des !== value && this.editContext.designConfig) {
            Reflect.set(this.editContext.designConfig, "mode", value);
            this.forceUpdate();
        }
    }
    onChangeFormName(event) {
        let des = this.editContext;
        if (des) {
            des.formName = event.target.value;
            if (this.editContext.refreshDesigner)
                this.editContext.refreshDesigner();
        }
        if (this.props.onFormNameUpdate) {
            this.props.onFormNameUpdate(event.target.value);
        }
    }
    render() {
        var _a, _b;
        return (_jsxs("div", Object.assign({ style: { display: "flex", flexDirection: "column", height: "100vh" }, "data-testid": "FormDesigner" }, { children: [_jsx(Topbar, { name: this.editContext.formName, onChangeName: this.onChangeFormName, editContext: this.editContext, isActionDisabled: !(this.editContext.mode === FormMode.FormDesign ||
                        this.editContext.mode === FormMode.LayoutDesign) || !this.editContext.lastSelectionElement, isRequiredActionGroup: this.editContext.mode !== FormMode.Runtime, onSave: this.props.onFormSave, onClose: this.props.onFormClose, prevItems: [
                        {
                            label: "Show Data",
                            items: FormDesignConstants.FORM_DATA_MODE.map((m) => ({
                                value: m,
                            })),
                            value: ((_a = this.editContext.designConfig) === null || _a === void 0 ? void 0 : _a.data) || "",
                            onSelect: this.onChangeSampleData,
                            type: IInjectTopItemType.SELECT,
                        },
                        {
                            label: "Display Format",
                            value: ((_b = this.editContext.designConfig) === null || _b === void 0 ? void 0 : _b.mode) || "",
                            items: [
                                {
                                    label: "Paper",
                                    icon: _jsx(PaperIcon, { alt: FormDesignConstants.FORM_MODE_PAPER }, void 0),
                                },
                                {
                                    label: "Gray",
                                    icon: _jsx(BrushIcon, { alt: FormDesignConstants.FORM_MODE_GRAY }, void 0),
                                },
                                {
                                    label: "Outline",
                                    icon: _jsx(OutlineIcon, { alt: FormDesignConstants.FORM_MODE_OUTLINE }, void 0),
                                },
                                {
                                    label: "White",
                                    icon: _jsx(NoneIcon, { alt: FormDesignConstants.FORM_MODE_WHITE }, void 0),
                                },
                                {
                                    label: FormDesignConstants.FORM_MODE_TABLET_HORIZONTAL,
                                    icon: (_jsx(TabletHorizontalIcon, { alt: FormDesignConstants.FORM_MODE_TABLET_HORIZONTAL }, void 0)),
                                },
                                {
                                    label: FormDesignConstants.FORM_MODE_TABLET_VERTICAL,
                                    icon: _jsx(TabletVerticalIcon, { alt: FormDesignConstants.FORM_MODE_TABLET_VERTICAL }, void 0),
                                },
                                {
                                    label: FormDesignConstants.FORM_MODE_PHONE_HORIZONTAL,
                                    icon: (_jsx(CellphoneHorizontalIcon, { alt: FormDesignConstants.FORM_MODE_PHONE_HORIZONTAL }, void 0)),
                                },
                                {
                                    label: FormDesignConstants.FORM_MODE_PHONE_VERTICAL,
                                    icon: _jsx(CellphoneVerticalIcon, { alt: FormDesignConstants.FORM_MODE_PHONE_VERTICAL }, void 0),
                                },
                            ],
                            onSelect: this.onUpdateDisplayMode,
                            type: IInjectTopItemType.ICONBUTTONGROUP,
                            wrapperStyle: { marginRight: this.editContext.mode === FormMode.Runtime ? "auto" : 0 },
                        },
                    ] }, void 0),
                _jsx(Sidebar, { items: this.tabs, value: this.editContext.mode, onChange: this.handleModeChange }, void 0)] }), void 0));
    }
}
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", FormContext)
], XFormDesigner.prototype, "setupProps", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onFormSave", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onFormClose", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onCopy", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onCut", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onDelete", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "handleModeChange", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onChangeSampleData", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onUpdateDisplayMode", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], XFormDesigner.prototype, "onChangeFormName", null);
//# sourceMappingURL=XFormDesigner.js.map