"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const getEditorSelection_1 = __importDefault(require("../lib/getEditorSelection"));
const handlePotentialBlockChange_1 = __importDefault(require("../lib/handlePotentialBlockChange"));
const checkKeybind_1 = __importDefault(require("../lib/helpers/checkKeybind"));
const focusAddedBlock_1 = __importDefault(require("../lib/postEditorMutations/focusAddedBlock"));
const focusRemovedBlock_1 = __importDefault(require("../lib/postEditorMutations/focusRemovedBlock"));
const mutations_1 = __importDefault(require("../mutations"));
const BlockWrapper_1 = __importDefault(require("./BlockWrapper"));
const mergeObjects_1 = __importDefault(require("../lib/helpers/mergeObjects"));
const handleDownArrowNavigation_1 = __importDefault(require("../lib/keybinds/handleDownArrowNavigation"));
const handleUpArrowNavigation_1 = __importDefault(require("../lib/keybinds/handleUpArrowNavigation"));
const createStyledTextRenderer_1 = __importDefault(require("./createStyledTextRenderer"));
const getDefaultProps = () => ({
    postMutations: {
        addBlock: [focusAddedBlock_1.default],
        removeBlock: [focusRemovedBlock_1.default]
    },
    renderers: {
        'text': (0, createStyledTextRenderer_1.default)({}, ''),
    },
    keybinds: [
        {
            keybind: 'ArrowDown',
            handler: handleDownArrowNavigation_1.default,
        },
        {
            keybind: 'ArrowUp',
            handler: handleUpArrowNavigation_1.default,
        }
    ],
    richTextKeybinds: [],
    blockWrappers: [
        BlockWrapper_1.default
    ]
});
const Editor = (props) => {
    const { startingBlocks, plugins } = props;
    const [blocks, setBlocks] = (0, react_1.useState)(startingBlocks);
    const editorRef = (0, react_1.useRef)(null);
    const defaultProps = (0, react_1.useMemo)(() => getDefaultProps(), []);
    const mergedProps = (0, react_1.useMemo)(() => (0, mergeObjects_1.default)(defaultProps, (plugins || []).reduce((acc, plugin) => (0, mergeObjects_1.default)(acc, plugin), props)), [props, plugins, defaultProps]);
    const { renderers, inlineBlocks, postMutations, keybinds, richTextKeybinds, blockWrappers, } = mergedProps;
    const editorMutations = (0, react_1.useMemo)(() => (Object.fromEntries(Object
        .entries(mutations_1.default)
        .map(([name, fn]) => {
        const mutation = (...args) => {
            var _a;
            // ~ Handle post mutations
            if (name === 'editBlock' && richTextKeybinds && editorRef.current) {
                const didTypeChange = (0, handlePotentialBlockChange_1.default)(args, blocks, editorMutations, richTextKeybinds, editorRef.current);
                if (didTypeChange)
                    return;
            }
            setBlocks((blocks) => {
                // @ts-ignore
                return fn(blocks, ...args);
            });
            const mutationsToPerform = (_a = postMutations === null || postMutations === void 0 ? void 0 : postMutations[name]) !== null && _a !== void 0 ? _a : [];
            mutationsToPerform === null || mutationsToPerform === void 0 ? void 0 : mutationsToPerform.forEach((mutation) => {
                // @ts-ignore
                mutation(blocks, ...args);
            });
        };
        return [name, mutation];
    }))), [
        blocks,
        postMutations,
        richTextKeybinds
    ]);
    (0, react_1.useEffect)(() => {
        if (!keybinds)
            return;
        const keydownListners = (keybinds.map(({ keybind, handler }) => {
            const listener = (event) => {
                if (!(0, checkKeybind_1.default)(keybind, event) || !editorRef.current)
                    return;
                const currentSelection = (0, getEditorSelection_1.default)(editorRef.current);
                handler(editorMutations, blocks, currentSelection, event);
            };
            return listener;
        }));
        keydownListners.forEach((listener) => {
            document.addEventListener('keydown', listener);
        });
        return () => {
            keydownListners.forEach((listener) => {
                document.removeEventListener('keydown', listener);
            });
        };
    }, [editorMutations, blocks]);
    return (<div style={{
            display: "flex",
            flexDirection: "column",
            gap: "1em"
        }} ref={editorRef}>
      {blocks.map((block) => {
            const { type, id } = block;
            const Renderer = renderers[type];
            if (!Renderer)
                return;
            const initialChild = (<Renderer id={block.id} mutations={editorMutations} properties={block.properties} inlineBlocks={inlineBlocks} type={block.type} editorRef={editorRef} key={id}/>);
            return (blockWrappers || [])
                .slice(-((blockWrappers === null || blockWrappers === void 0 ? void 0 : blockWrappers.length) || 0))
                .reduce((child, Wrapper) => (<Wrapper block={block} mutations={editorMutations}>
                {child}
              </Wrapper>), initialChild);
        })}
    </div>);
};
exports.default = Editor;
//# sourceMappingURL=Editor.jsx.map