import { __decorate, __metadata } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from "react";
import styled from "styled-components";
import { Button, DialogTitle, DialogContentText, DialogContent, DialogActions, Dialog, MenuItem, } from "@material-ui/core";
import { UIControlRegistration } from "./RegisterUIControl";
import { DragDropContext } from "react-beautiful-dnd";
import { XFormDesignerLayoutPanel } from "./XFormDesignerLayoutPanel";
import { ToolBox } from "../Components/ToolBox";
import { AutoBind } from "../../Common/AutoBind";
import "./XFormAndLayoutDesignPanel.css";
import { EditLayerStyledAccordionDetails, EditLayerStyledAccordionSummary, EditLayerStyledTypography, EditLayerConfigArea, EditLayerStyledAccordion, ContextMenuForControl, VerticalButton, } from "../../CommonUI/CommonStyles";
import { FormDesignConstants, FormMode } from "../FormDesignConstants";
import { ExpandIcon } from "../../CommonUI/Icon/ExpandIcon";
import { CopyWhiteIcon } from "../../CommonUI/Icon/CopyWhiteIcon";
import { CutWhiteIcon } from "../../CommonUI/Icon/CutWhiteIcon";
import { DeleteWhiteIcon } from "../../CommonUI/Icon/DeleteWhiteIcon";
import { ValidationErrorRendering } from "../Components/ValidationErrorRendering";
import { ObserveState } from "../../CommonUI/StateManagement/ObserveState";
import { DockedSidebar } from "../../CommonUI/BuildUI/DockSidebar";
import { DropdownIcon } from "../../CommonUI/Icon/DropdownIcon";
export const CONFIG_FORM_KEY = "configForm";
const Designer = styled.div `
    display: flex;
    width: 100%;
    overflow: hidden;
    position: relative;
`;
export class XFormAndLayoutDesignPanel extends React.Component {
    constructor() {
        super(...arguments);
        this.configFormNode = React.createRef();
        this.handleClickOutside = (event) => {
            var _a, _b;
            if (this.configFormNode.current &&
                event.target instanceof Node &&
                !this.configFormNode.current.contains(event.target) && ((_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.expandedConfigPanel) &&
                document.getElementsByClassName("MuiDialog-root").length === 0 &&
                document.getElementsByClassName("MuiPopover-paper").length === 0) {
                (_b = this.props.editContext) === null || _b === void 0 ? void 0 : _b.unSelectControl();
            }
        };
        this.onToggleExpandedConfigPanel = () => {
            var _a, _b;
            if (!((_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.isMovingConfigPanel)) {
                if (this.props.editContext)
                    this.props.editContext.expandedConfigPanel = !((_b = this.props.editContext) === null || _b === void 0 ? void 0 : _b.expandedConfigPanel);
                this.forceUpdate();
            }
        };
        this.onDragMovingConfigPanel = () => {
            if (this.props.editContext)
                this.props.editContext.isMovingConfigPanel = true;
        };
        this.onEndMovingConfigPanel = () => {
            setTimeout(() => {
                if (this.props.editContext)
                    this.props.editContext.isMovingConfigPanel = false;
                this.forceUpdate();
            }, 500);
        };
        this.deleteControl = () => {
            if (this.props.editContext.deleteControl) {
                this.props.editContext.form.remove(this.props.editContext.deleteControl);
                this.props.editContext.deleteControl = null;
                this.forceUpdate();
            }
        };
        this.cancelDeleteControl = () => {
            this.props.editContext.deleteControl = null;
            this.forceUpdate();
        };
    }
    componentDidMount() {
        document.addEventListener("mousedown", this.handleClickOutside);
    }
    componentWillUnmount() {
        document.removeEventListener("mousedown", this.handleClickOutside);
    }
    render() {
        return (_jsx(ObserveState, { listenTo: this.props.editContext, control: () => {
                var _a;
                return (_jsx(DragDropContext, Object.assign({ onDragStart: this.onDragStart, onDragEnd: this.onDragEnd }, { children: _jsxs(Designer, { children: [_jsx(ToolBox, { onSelectFormDefaultConfig: () => {
                                    if (this.props.editContext)
                                        this.props.editContext.selectControl(CONFIG_FORM_KEY);
                                }, mode: this.props.editContext.mode }, void 0),
                            _jsx(DockedSidebar, { sidebar: () => this.renderEditUI(), content: () => _jsx(XFormDesignerLayoutPanel, { editContext: this.props.editContext }, void 0), sidebarWidth: 350, open: this.props.editContext.isShowEditLayer, onClose: this.props.editContext.hideEditLayer, toogleIcon: () => {
                                    var _a;
                                    return (_jsx(VerticalButton, Object.assign({ open: this.props.editContext.isShowEditLayer, onClick: (e) => {
                                            e.stopPropagation();
                                            e.preventDefault();
                                            this.props.editContext.toggleEditLayer();
                                        }, endIcon: _jsx(DropdownIcon, {}, void 0), color: "primary", variant: "contained" }, { children: ((_a = this.props.editContext.getSelectedControl()) === null || _a === void 0 ? void 0 : _a.toString()) || "Form" }), void 0));
                                } }, void 0),
                            this.props.editContext.mode === FormMode.FormDesign && (_jsx(ObserveState, { listenTo: (_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.controlContexts, control: () => {
                                    var _a, _b;
                                    return (_jsx(ValidationErrorRendering, { validations: (_b = (_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.controlContexts.getAllDesignIssues()) !== null && _b !== void 0 ? _b : [] }, void 0));
                                }, properties: ["validationIssues"] }, void 0)),
                            _jsxs(Dialog, Object.assign({ open: !!this.props.editContext.deleteControl }, { children: [_jsx(DialogTitle, { children: "Warning" }, void 0),
                                    _jsx(DialogContent, { children: _jsx(DialogContentText, { children: "Are you sure to delete this?" }, void 0) }, void 0),
                                    _jsxs(DialogActions, { children: [_jsx(Button, Object.assign({ variant: "contained", color: "primary", onClick: this.deleteControl }, { children: "OK" }), void 0),
                                            _jsx(Button, Object.assign({ variant: "contained", onClick: this.cancelDeleteControl }, { children: "Cancel" }), void 0)] }, void 0)] }), void 0), this.renderContextMenuUI()] }, "formdesigner") }), void 0));
            } }, void 0));
    }
    renderEditUI() {
        var _a;
        let editUIComponent = this.props.editContext.getEditUI(CONFIG_FORM_KEY);
        let selectedControl = this.props.editContext.getSelectedControl(CONFIG_FORM_KEY);
        if (!editUIComponent)
            return null;
        return (_jsx(EditLayerConfigArea, Object.assign({ ref: this.configFormNode }, { children: _jsxs(EditLayerStyledAccordion, Object.assign({ expanded: (_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.expandedConfigPanel, onChange: this.onToggleExpandedConfigPanel, defaultExpanded: true }, { children: [_jsx(EditLayerStyledAccordionSummary, Object.assign({ expandIcon: _jsx(ExpandIcon, {}, void 0) }, { children: _jsxs(EditLayerStyledTypography, Object.assign({ variant: "subtitle1", classes: { root: "config-form-header" } }, { children: ["Edit: ", (selectedControl === null || selectedControl === void 0 ? void 0 : selectedControl.toString()) || "Form Config"] }), void 0) }), void 0),
                    _jsx(EditLayerStyledAccordionDetails, Object.assign({ classes: { root: "config-form-content" } }, { children: _jsx(ObserveState, { listenTo: selectedControl, control: () => {
                                return editUIComponent === null || editUIComponent === void 0 ? void 0 : editUIComponent.create();
                            } }, void 0) }), void 0)] }), void 0) }), void 0));
    }
    renderContextMenuUI() {
        let contextControl = this.props.editContext.contextControl;
        if (contextControl) {
            return (_jsxs(ContextMenuForControl, Object.assign({ open: !!contextControl, onClose: this.props.editContext.unselectContextControl, anchorReference: "anchorPosition", anchorPosition: contextControl.mouseY !== null && contextControl.mouseX !== null
                    ? { top: contextControl.mouseY, left: contextControl.mouseX }
                    : undefined }, { children: [_jsxs(MenuItem, Object.assign({ onClick: () => this.props.editContext.onCopy(contextControl.selectedId), "data-testid": "btn-context-copy" }, { children: [_jsx(CopyWhiteIcon, {}, void 0), " Copy"] }), void 0),
                    _jsxs(MenuItem, Object.assign({ onClick: () => this.props.editContext.onCut(contextControl.selectedId), "data-testid": "btn-context-cut" }, { children: [_jsx(CutWhiteIcon, {}, void 0), " Cut"] }), void 0),
                    _jsxs(MenuItem, Object.assign({ onClick: () => this.props.editContext.onDelete(contextControl.selectedId), "data-testid": "btn-context-paste" }, { children: [_jsx(DeleteWhiteIcon, {}, void 0), " Delete"] }), void 0)] }), void 0));
        }
    }
    onDragStart(result) {
        let control;
        if (Object.keys(UIControlRegistration).indexOf(result.draggableId) !== -1) {
            // @ts-ignore
            let registeredControl = UIControlRegistration[result.draggableId];
            let val = new registeredControl.prototype.constructor();
            // @ts-ignore
            control = val;
        }
        else {
            control = this.props.editContext.form.find(result.draggableId);
        }
        if (control) {
            if (this.props.editContext)
                this.props.editContext.selectControl(control.id);
            this.updateUI();
        }
        else {
            if (this.props.editContext)
                this.props.editContext.unSelectControl();
            this.updateUI();
        }
    }
    onDragEnd(result) {
        // if not destination... then we should not do anything
        if (!result.destination)
            return;
        let control;
        if (Object.keys(UIControlRegistration).indexOf(result.draggableId) !== -1) {
            // @ts-ignore
            let registeredControl = UIControlRegistration[result.draggableId];
            let val = new registeredControl.prototype.constructor();
            // @ts-ignore
            control = val;
        }
        else {
            control = this.props.editContext.form.find(result.draggableId);
        }
        if (control)
            control.setFormContext(this.props.editContext);
        if (result.destination.droppableId === FormDesignConstants.LAYOUT_FORM_KEY_NAME) {
            // we are moving things around or adjusting base form
            // containers
            if (control) {
                if (result.destination.droppableId === result.source.droppableId) {
                    // changing order
                    this.props.editContext.form.setOrder(control.id, result.destination.index);
                }
                else {
                    // adding new
                    this.props.editContext.form.add(control);
                    this.props.editContext.form.setOrder(control.id, result.destination.index);
                }
            }
        }
        else {
            let fromContainer = this.props.editContext.form.find(result.source.droppableId);
            let toContainer = this.props.editContext.form.find(result.destination.droppableId);
            if (!toContainer || !control) {
                console.log("something not found");
                console.log(result.draggableId);
                return;
                //            throw new Error('something could not be found');
            }
            if (fromContainer && fromContainer.id === toContainer.id) {
                // its same container move
                toContainer.setOrder(control.id, result.destination.index);
            }
            else {
                if (fromContainer)
                    fromContainer.remove(control);
                toContainer.add(control, result.destination.index);
            }
            if (control && this.props.editContext) {
                this.props.editContext.selectControl(control.id);
            }
        }
        // this.dragPlaceholder = null;
        this.updateUI();
    }
    updateUI() {
        var _a;
        (_a = this.props.editContext) === null || _a === void 0 ? void 0 : _a.refreshDesigner();
    }
}
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormAndLayoutDesignPanel.prototype, "renderEditUI", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], XFormAndLayoutDesignPanel.prototype, "onDragStart", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], XFormAndLayoutDesignPanel.prototype, "onDragEnd", null);
__decorate([
    AutoBind,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], XFormAndLayoutDesignPanel.prototype, "updateUI", null);
//# sourceMappingURL=XFormAndLayoutDesignPanel.js.map