import { createLexicalComposerContext, LexicalComposerContext, } from "./LexicalComposerContext";
import { useCollaborationContext } from "./LexicalCollaborationContext";
import { createEffect, onCleanup, useContext } from "solid-js";
import warnOnlyOnce from "./shared/warnOnlyOnce";
function getTransformSetFromKlass(klass) {
    const transform = klass.transform();
    return new Set(transform ? [transform] : []);
}
const initialNodesWarning = warnOnlyOnce(`LexicalNestedComposer initialNodes is deprecated and will be removed in v0.32.0, it has never worked correctly.\nYou can configure your editor's nodes with createEditor({nodes: [], parentEditor: $getEditor()})`);
const explicitNamespaceWarning = warnOnlyOnce(`LexicalNestedComposer initialEditor should explicitly initialize its namespace when the node configuration differs from the parentEditor. For backwards compatibility, the namespace will be initialized from parentEditor until v0.32.0, but this has always had incorrect copy/paste behavior when the configuration differed.\nYou can configure your editor's namespace with createEditor({namespace: 'nested-editor-namespace', nodes: [], parentEditor: $getEditor()}).`);
export function LexicalNestedComposer(props) {
    let wasCollabPreviouslyReadyRef = false;
    const parentContext = useContext(LexicalComposerContext);
    if (parentContext == null) {
        throw Error("Unexpected parent context null on a nested composer");
    }
    const [parentEditor, { getTheme: getParentTheme }] = parentContext;
    const composerTheme = props.initialTheme || getParentTheme() || undefined;
    const context = createLexicalComposerContext(parentContext, composerTheme);
    const initialEditor = props.initialEditor;
    if (composerTheme !== undefined) {
        initialEditor._config.theme = composerTheme;
    }
    initialEditor._parentEditor = initialEditor._parentEditor || parentEditor;
    const createEditorArgs = initialEditor._createEditorArgs;
    const explicitNamespace = createEditorArgs && createEditorArgs.namespace;
    if (!props.initialNodes) {
        if (!(createEditorArgs && createEditorArgs.nodes)) {
            const parentNodes = (props.initialEditor._nodes = new Map(parentEditor._nodes));
            if (!explicitNamespace) {
                // This is the only safe situation to inherit the parent's namespace
                initialEditor._config.namespace = parentEditor._config.namespace;
            }
            for (const [type, entry] of parentNodes) {
                initialEditor._nodes.set(type, {
                    exportDOM: entry.exportDOM,
                    klass: entry.klass,
                    replace: entry.replace,
                    replaceWithKlass: entry.replaceWithKlass,
                    transforms: getTransformSetFromKlass(entry.klass),
                });
            }
        }
        else if (!explicitNamespace) {
            initialNodesWarning();
            if (!explicitNamespace) {
                explicitNamespaceWarning();
                initialEditor._config.namespace = parentEditor._config.namespace;
            }
        }
    }
    else {
        for (let klass of props.initialNodes) {
            let replace = null;
            let replaceWithKlass = null;
            if (typeof klass !== "function") {
                const options = klass;
                klass = options.replace;
                replace = options.with;
                replaceWithKlass = options.withKlass || null;
            }
            const registeredKlass = props.initialEditor._nodes.get(klass.getType());
            props.initialEditor._nodes.set(klass.getType(), {
                exportDOM: registeredKlass ? registeredKlass.exportDOM : undefined,
                klass,
                replace,
                replaceWithKlass,
                transforms: getTransformSetFromKlass(klass),
            });
        }
    }
    // If collaboration is enabled, make sure we don't render the children until the collaboration subdocument is ready.
    const { isCollabActive, yjsDocMap } = useCollaborationContext();
    const isCollabReady = () => props.skipCollabChecks ||
        wasCollabPreviouslyReadyRef ||
        yjsDocMap.has(props.initialEditor.getKey());
    createEffect(() => {
        if (isCollabReady()) {
            wasCollabPreviouslyReadyRef = true;
        }
    });
    // Update `isEditable` state of nested editor in response to the same change on parent editor.
    createEffect(() => {
        if (!props.skipEditableListener) {
            const editableListener = (editable) => initialEditor.setEditable(editable);
            editableListener(parentEditor.isEditable());
            onCleanup(parentEditor.registerEditableListener(editableListener));
        }
    });
    return (<LexicalComposerContext.Provider value={[props.initialEditor, context]}>
      {!isCollabActive || isCollabReady() ? props.children : null}
    </LexicalComposerContext.Provider>);
}
