import { createElement } from "react";
import { Element } from "slate";
import { BindingError } from "@contember/binding";
import { ReactEditor } from "slate-react";
import { ReferenceElementRenderer } from "../renderers/ReferenceElementRenderer.js";
import { getDiscriminatedDatum } from "../../../discrimination/getDiscriminatedDatum.js";
const referenceElementType = "reference";
const isReferenceElement = (node) => Element.isElement(node) && node.type === referenceElementType;
const findElementPathFallback = (parent, element) => {
  for (const i in parent.children) {
    const child = parent.children[i];
    if (element === child) {
      return [Number(i)];
    }
    if (Element.isAncestor(child)) {
      const result = findElementPathFallback(child, element);
      if (result !== void 0) {
        return [Number(i), ...result];
      }
    }
  }
  return void 0;
};
const createReferenceElementPlugin = (args) => {
  return {
    type: referenceElementType,
    render: (props) => {
      if (!args.referenceDiscriminationField) {
        throw new Error();
      }
      return /* @__PURE__ */ createElement(ReferenceElementRenderer, {
        ...args,
        ...props,
        referenceDiscriminationField: args.referenceDiscriminationField
      });
    },
    canContainAnyBlocks: true,
    isVoid: ({ element, editor }) => {
      if (args.referenceDiscriminationField === void 0) {
        throw new BindingError();
      }
      const path = (() => {
        try {
          return ReactEditor.findPath(editor, element);
        } catch (e) {
          return findElementPathFallback(editor, element);
        }
      })();
      if (!path) {
        return false;
      }
      let referencedEntity;
      try {
        referencedEntity = args.getReferencedEntity(path, element.referenceId);
      } catch (e) {
        return false;
      }
      const discriminationField = referencedEntity.getRelativeSingleField(args.referenceDiscriminationField);
      const selectedReference = getDiscriminatedDatum(args.editorReferenceBlocks, discriminationField)?.datum;
      if (selectedReference === void 0) {
        throw new BindingError();
      }
      return selectedReference.template === void 0;
    }
  };
};
export { createReferenceElementPlugin, isReferenceElement, referenceElementType };
//# sourceMappingURL=ReferenceElement.js.map
