import { Editor, Node, Text, Transforms } from "slate";
import { jsx } from "slate-hyperscript";
import { parseFragment } from "parse5";
import { Slate } from "@makeswift/controls";
import { BlockType, InlineType } from "../../../slate/types";
import { createEditorWithPlugins, stringToPath } from "./translations-core";
function deserializeTranslationHtmlString(el, translationKey) {
  if (el.nodeName === "#document-fragment") {
    const children = Array.from(el.childNodes).map((element) => deserializeTranslationHtmlString(element)).flat();
    if (children.length === 0) {
      children.push(jsx("text", {}, ""));
    }
    return children;
  }
  if (el.nodeName === "#text" && "value" in el) {
    return [jsx("text", { translationKey: translationKey ?? void 0 }, el.value)];
  }
  if ("namespaceURI" in el) {
    const translationKey2 = el.attrs.find((a) => a.name === "key")?.value ?? void 0;
    const children = Array.from(el.childNodes).map((element) => deserializeTranslationHtmlString(element, translationKey2)).flat();
    if (children.length === 0) {
      children.push(jsx("text", {}, ""));
    }
    switch (el.nodeName) {
      case "code":
        return [jsx("element", { type: InlineType.Code, translationKey: translationKey2 }, children)];
      case "sub":
        return [jsx("element", { type: InlineType.SubScript, translationKey: translationKey2 }, children)];
      case "sup":
        return [jsx("element", { type: InlineType.SuperScript, translationKey: translationKey2 }, children)];
      case "a":
        return [jsx("element", { type: InlineType.Link, translationKey: translationKey2 }, children)];
      default:
        return children;
    }
  }
  return [];
}
function mergeTranslatedNodes(nodes, translatedData, plugins) {
  const sourceEditor = createEditorWithPlugins(plugins);
  const targetEditor = createEditorWithPlugins(plugins);
  sourceEditor.children = nodes;
  sourceEditor.typographyNormalizationDirection = "up";
  Editor.normalize(sourceEditor, { force: true });
  Object.entries(translatedData).reverse().forEach(([blockStringPath, htmlString]) => {
    const blockPath = stringToPath(blockStringPath);
    if (blockPath.length === 0)
      return;
    const html = parseFragment(htmlString);
    const inlineDescendants = deserializeTranslationHtmlString(html);
    targetEditor.children = [{ type: BlockType.Default, children: inlineDescendants }];
    targetEditor.typographyNormalizationDirection = "neutral";
    Editor.normalize(targetEditor, { force: true });
    for (const [descendant, absolutePathToTargetNode] of Node.descendants(targetEditor)) {
      if (!Text.isText(descendant) && !Slate.isInline(descendant) || descendant.translationKey == null || descendant.translationKey === "") {
        continue;
      }
      const relativePathToSourceNode = stringToPath(descendant.translationKey);
      const absolutePathToSourceNode = [...blockPath, ...relativePathToSourceNode];
      const [sourceNode] = Editor.node(sourceEditor, absolutePathToSourceNode);
      if (Text.isText(sourceNode) && Text.isText(descendant)) {
        const { translationKey, text, ...rest } = sourceNode;
        Transforms.setNodes(targetEditor, rest, { at: absolutePathToTargetNode });
        Transforms.unsetNodes(targetEditor, "translationKey", { at: absolutePathToTargetNode });
      } else if (Slate.isInline(sourceNode) && Slate.isInline(descendant)) {
        const { translationKey, children, ...rest } = sourceNode;
        Transforms.setNodes(targetEditor, rest, { at: absolutePathToTargetNode });
        Transforms.unsetNodes(targetEditor, "translationKey", { at: absolutePathToTargetNode });
      }
    }
    const translatedChildren = targetEditor.children.at(0)?.children;
    Editor.withoutNormalizing(sourceEditor, () => {
      Array.from(Node.children(sourceEditor, blockPath)).reverse().forEach(([_, path]) => {
        Transforms.removeNodes(sourceEditor, { at: path });
      });
      Transforms.insertNodes(sourceEditor, translatedChildren, { at: [...blockPath, 0] });
    });
  });
  sourceEditor.typographyNormalizationDirection = "down";
  Editor.normalize(sourceEditor, { force: true });
  return sourceEditor.children;
}
export {
  mergeTranslatedNodes
};
//# sourceMappingURL=merge-translations.js.map