import { Excalidraw } from '@excalidraw/excalidraw';
import * as React from 'react';
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import Button from '../../ui/Button';
import Modal from '../../ui/Modal';
export const useCallbackRefState = () => {
    const [refValue, setRefValue] = React.useState(null);
    const refCallback = React.useCallback((value) => setRefValue(value), []);
    return [refValue, refCallback];
};
/**
 * @explorer-desc
 * A component which renders a modal with Excalidraw (a painting app)
 * which can be used to export an editable image
 */
export default function ExcalidrawModal({ closeOnClickOutside = false, initialAppState, initialElements, initialFiles, isShown = false, onClose, onDelete, onSave, }) {
    const excaliDrawModelRef = useRef(null);
    const [excalidrawAPI, excalidrawAPIRefCallback] = useCallbackRefState();
    const [discardModalOpen, setDiscardModalOpen] = useState(false);
    const [elements, setElements] = useState(initialElements);
    const [files, setFiles] = useState(initialFiles);
    useEffect(() => {
        if (excaliDrawModelRef.current !== null) {
            excaliDrawModelRef.current.focus();
        }
    }, []);
    useEffect(() => {
        var _a;
        let modalOverlayElement = null;
        const clickOutsideHandler = (event) => {
            const target = event.target;
            if (excaliDrawModelRef.current !== null &&
                !excaliDrawModelRef.current.contains(target) &&
                closeOnClickOutside) {
                onDelete();
            }
        };
        if (excaliDrawModelRef.current !== null) {
            modalOverlayElement = (_a = excaliDrawModelRef.current) === null || _a === void 0 ? void 0 : _a.parentElement;
            if (modalOverlayElement !== null) {
                modalOverlayElement === null || modalOverlayElement === void 0 ? void 0 : modalOverlayElement.addEventListener('click', clickOutsideHandler);
            }
        }
        return () => {
            if (modalOverlayElement !== null) {
                modalOverlayElement === null || modalOverlayElement === void 0 ? void 0 : modalOverlayElement.removeEventListener('click', clickOutsideHandler);
            }
        };
    }, [closeOnClickOutside, onDelete]);
    useLayoutEffect(() => {
        const currentModalRef = excaliDrawModelRef.current;
        const onKeyDown = (event) => {
            if (event.key === 'Escape') {
                onDelete();
            }
        };
        if (currentModalRef !== null) {
            currentModalRef.addEventListener('keydown', onKeyDown);
        }
        return () => {
            if (currentModalRef !== null) {
                currentModalRef.removeEventListener('keydown', onKeyDown);
            }
        };
    }, [elements, files, onDelete]);
    const save = () => {
        if (elements.filter((el) => !el.isDeleted).length > 0) {
            const appState = excalidrawAPI === null || excalidrawAPI === void 0 ? void 0 : excalidrawAPI.getAppState();
            // We only need a subset of the state
            const partialState = {
                exportBackground: appState === null || appState === void 0 ? void 0 : appState.exportBackground,
                exportScale: appState === null || appState === void 0 ? void 0 : appState.exportScale,
                exportWithDarkMode: (appState === null || appState === void 0 ? void 0 : appState.theme) === 'dark',
                isBindingEnabled: appState === null || appState === void 0 ? void 0 : appState.isBindingEnabled,
                isLoading: appState === null || appState === void 0 ? void 0 : appState.isLoading,
                name: appState === null || appState === void 0 ? void 0 : appState.name,
                theme: appState === null || appState === void 0 ? void 0 : appState.theme,
                viewBackgroundColor: appState === null || appState === void 0 ? void 0 : appState.viewBackgroundColor,
                viewModeEnabled: appState === null || appState === void 0 ? void 0 : appState.viewModeEnabled,
                zenModeEnabled: appState === null || appState === void 0 ? void 0 : appState.zenModeEnabled,
                zoom: appState === null || appState === void 0 ? void 0 : appState.zoom,
            };
            onSave(elements, partialState, files);
        }
        else {
            // delete node if the scene is clear
            onDelete();
        }
    };
    const discard = () => {
        if (elements.filter((el) => !el.isDeleted).length === 0) {
            // delete node if the scene is clear
            onDelete();
        }
        else {
            // Otherwise, show confirmation dialog before closing
            setDiscardModalOpen(true);
        }
    };
    function ShowDiscardDialog() {
        return (React.createElement(Modal, { closeOnClickOutside: false, onClose: () => {
                setDiscardModalOpen(false);
            }, title: 'Discard' },
            "Are you sure you want to discard the changes?",
            React.createElement("div", { className: 'ExcalidrawModal__discardModal' },
                React.createElement(Button, { onClick: () => {
                        setDiscardModalOpen(false);
                        onClose();
                    } }, "Discard"),
                ' ',
                React.createElement(Button, { onClick: () => {
                        setDiscardModalOpen(false);
                    } }, "Cancel"))));
    }
    if (isShown === false) {
        return null;
    }
    const onChange = (els, _, fls) => {
        setElements(els);
        setFiles(fls);
    };
    return createPortal(React.createElement("div", { className: 'ExcalidrawModal__overlay', role: 'dialog' },
        React.createElement("div", { ref: excaliDrawModelRef, className: 'ExcalidrawModal__modal', tabIndex: -1 },
            React.createElement("div", { className: 'ExcalidrawModal__row' },
                discardModalOpen && React.createElement(ShowDiscardDialog, null),
                React.createElement(Excalidraw, { excalidrawAPI: excalidrawAPIRefCallback, initialData: {
                        appState: initialAppState || { isLoading: false },
                        elements: initialElements,
                        files: initialFiles,
                    }, onChange: onChange }),
                React.createElement("div", { className: 'ExcalidrawModal__actions' },
                    React.createElement("button", { className: 'action-button', onClick: discard, type: 'button' }, "Discard"),
                    React.createElement("button", { className: 'action-button', onClick: save, type: 'button' }, "Save"))))), document.body);
}
//# sourceMappingURL=ExcalidrawModal.js.map