import { Plugin, PluginKey } from "../../../../../pm/state.js";
import { Decoration, DecorationSet } from "../../../../../pm/view.js";
import { codeBlockType } from "../../CodeBlockSpecs/index.js";
const pluginKey = new PluginKey('code_block_line_wrapping');
const WRAPPING_SPEC_KEY = '__code_block_line_wrapping';
const WRAPPING_SPEC_VALUE = true;
const isLineWrappingDecoration = (deco) => deco.spec?.[WRAPPING_SPEC_KEY] === WRAPPING_SPEC_VALUE;
/** @internal */
export const hasLineWrappingDecoration = (decorations) => {
    return decorations.some(isLineWrappingDecoration);
};
/** @internal */
export const isNodeHasLineWrapping = (state, pos) => {
    const node = state.doc.nodeAt(pos);
    if (!node || node.type !== codeBlockType(state.doc.type.schema))
        return false;
    const decos = pluginKey.getState(state)?.decorations.find(pos + 1, pos + node.nodeSize - 1);
    return decos?.some(isLineWrappingDecoration) ?? false;
};
/** @internal */
export function enableLineWrapping(tr, pos) {
    return tr.setMeta(pluginKey, { type: 'add', pos });
}
/** @internal */
export function disableLineWrapping(tr, pos) {
    return tr.setMeta(pluginKey, { type: 'remove', pos });
}
/** @internal */
export const codeBlockLineWrappingPlugin = () => {
    return new Plugin({
        key: pluginKey,
        state: {
            init() {
                return {
                    decorations: DecorationSet.empty,
                };
            },
            apply(tr, value) {
                let decorations = value.decorations.map(tr.mapping, tr.doc);
                if (tr.getMeta(pluginKey)) {
                    const meta = tr.getMeta(pluginKey);
                    if (meta.type === 'add') {
                        const node = tr.doc.nodeAt(meta.pos);
                        if (node?.type === codeBlockType(tr.doc.type.schema)) {
                            const from = meta.pos;
                            const to = meta.pos + node.nodeSize;
                            decorations = decorations.add(tr.doc, [
                                Decoration.node(from, to, {}, { [WRAPPING_SPEC_KEY]: WRAPPING_SPEC_VALUE }),
                            ]);
                        }
                    }
                    else if (meta.type === 'remove') {
                        const node = tr.doc.nodeAt(meta.pos);
                        if (node?.type === codeBlockType(tr.doc.type.schema)) {
                            const start = meta.pos + 1;
                            const end = meta.pos + node.nodeSize - 1;
                            const found = decorations.find(start, end);
                            decorations = decorations.remove(found);
                        }
                    }
                }
                return { decorations };
            },
        },
        props: {
            decorations(state) {
                return pluginKey.getState(state)?.decorations;
            },
        },
    });
};
//# sourceMappingURL=codeBlockLineWrappingPlugin.js.map
