import { createHtmlInserter } from "./create-html-inserter";
export const inserterFactory = (view, contentConverter, trigger) => {
    return {
        insert: createNodeAndTextInserter(view, trigger),
        insertHtml: createHtmlInserter(view, contentConverter, trigger.position, dispatchTransaction),
        stopTrigger: () => stopTriggerTransaction(view),
    };
};
const createNodeAndTextInserter = (view, trigger) => (input) => {
    const schema = view.state.schema;
    let node;
    try {
        node = createNode(input, schema);
    }
    catch (error) {
        console.error(error.message);
        return;
    }
    const spaceNode = schema.text(' ');
    const fragment = schema.nodes.doc.create(null, [node, spaceNode]);
    dispatchTransaction(view, trigger.position, fragment);
};
const stopTriggerTransaction = (view) => {
    const { state, dispatch } = view;
    const transaction = state.tr;
    transaction.setMeta('stopTrigger', true);
    dispatch(transaction);
};
const dispatchTransaction = (view, startPos, fragment) => {
    const state = view.state;
    const fromPos = state.selection.$from.pos;
    const dispatch = view.dispatch;
    const transaction = state.tr.replaceWith(startPos, fromPos, fragment);
    transaction.setMeta('stopTrigger', true);
    dispatch(transaction);
};
const createNode = (input, schema) => {
    var _a;
    if (typeof input === 'string') {
        return schema.text(input);
    }
    const node = input.node;
    if (typeof node === 'string') {
        return schema.text(node);
    }
    const customNode = getCustomNode(node.tagName, schema);
    const childNodes = ((_a = input.children) !== null && _a !== void 0 ? _a : [])
        .map((child) => createNode(child, schema))
        .filter(Boolean);
    return customNode.create(node.attributes, childNodes);
};
const getCustomNode = (name, schema) => {
    const customNode = Object.values(schema.nodes).find((prosemirrorNode) => prosemirrorNode.name === name);
    if (!customNode) {
        throw new Error(`No custom element has been registered for node ${name}`);
    }
    return customNode;
};
