import { jsxs, Fragment, jsx } from "react/jsx-runtime";
import { useEntity, BindingError, Entity } from "@contember/react-binding";
import { EditorPlaceholder, Box, ActionableBox, FieldSet } from "@contember/ui";
import { memo, useCallback } from "react";
import { Transforms } from "slate";
import { useSlateStatic, useSelected, ReactEditor } from "slate-react";
import { getDiscriminatedDatum } from "../../../discrimination/getDiscriminatedDatum.js";
import { getDiscriminatedBlock } from "../../../blocks/getDiscriminatedBlock.js";
import { BlockElement } from "../../baseEditor/BlockElement.js";
const ReferenceElementRenderer = memo((props) => {
  const editor = useSlateStatic();
  const selected = useSelected();
  const referencedEntity = useEntity();
  const discriminationField = referencedEntity.getRelativeSingleField(props.referenceDiscriminationField);
  const selectedReference = getDiscriminatedDatum(props.editorReferenceBlocks, discriminationField)?.datum;
  if (!selectedReference) {
    throw new BindingError(`BlockEditor: Trying to render a reference with an undefined reference type.`);
  }
  const elementTemplate = selectedReference.template;
  const isEditable = elementTemplate !== void 0;
  const onContainerClick = useCallback(
    (e) => {
      if (e.target === e.currentTarget) {
        const path = ReactEditor.findPath(editor, props.element);
        Transforms.select(editor, path);
      }
    },
    [editor, props.element]
  );
  const onRemove = useCallback(() => {
    const path = ReactEditor.findPath(editor, props.element);
    Promise.resolve().then(() => {
      Transforms.removeNodes(editor, {
        at: path
      });
    });
  }, [editor, props.element]);
  let blockBody;
  let renderedBlock = selectedReference;
  let isFullWidth = true;
  if (elementTemplate !== void 0) {
    const contentTemplate = elementTemplate.blockContent;
    if (contentTemplate === void 0) {
      throw new BindingError(
        `BlockEditor: All block reference elements must at least use the BlockEditor.ContentOutlet component!

It appears that other BlockEditor._____ components have been used but the BlockEditor.ContentOutlet is missing or isn't at the very top level.`
      );
    }
    const placeholder = contentTemplate.value.placeholder;
    const showPlaceholder = placeholder !== void 0 && props.element.children.length === 1 && props.element.children[0]?.text === "";
    blockBody = /* @__PURE__ */ jsxs(Fragment, { children: [
      !!contentTemplate.nodeBefore && /* @__PURE__ */ jsx("div", { contentEditable: false, children: contentTemplate.nodeBefore }),
      showPlaceholder ? /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
        /* @__PURE__ */ jsx("div", { style: { position: "absolute", pointerEvents: "none" }, contentEditable: false, children: /* @__PURE__ */ jsx(EditorPlaceholder, { children: placeholder }) }),
        /* @__PURE__ */ jsx("div", { children: props.children })
      ] }) : /* @__PURE__ */ jsx("div", { children: props.children }),
      !!contentTemplate.nodeAfter && /* @__PURE__ */ jsx("div", { contentEditable: false, children: contentTemplate.nodeAfter })
    ] });
  } else if (props.embedReferenceDiscriminateBy !== void 0 && discriminationField.hasValue(props.embedReferenceDiscriminateBy)) {
    if (props.embedContentDiscriminationField === void 0 || props.embedHandlers === void 0 || props.embedSubBlocks === void 0) {
      throw new BindingError(
        `BlockEditor: Trying to render an embed element without all the correct settings. Check the related BlockEditor props.`
      );
    }
    const embedTypeDiscriminant = referencedEntity.getRelativeSingleField(props.embedContentDiscriminationField);
    const embedHandler = getDiscriminatedDatum(props.embedHandlers, embedTypeDiscriminant);
    const subBlock = getDiscriminatedBlock(props.embedSubBlocks, embedTypeDiscriminant);
    if (embedHandler === void 0) {
      throw new BindingError(`BlockEditor: Missing handler for embed of type '${embedTypeDiscriminant.value}'.`);
    }
    if (subBlock === void 0) {
      throw new BindingError(`BlockEditor: Missing Block for embed of type '${embedTypeDiscriminant.value}'.`);
    }
    isFullWidth = false;
    renderedBlock = subBlock.datum;
    blockBody = /* @__PURE__ */ jsx(
      "div",
      {
        style: { display: "flex" },
        children: /* @__PURE__ */ jsx(EmbedElementRendererInner, { handler: embedHandler.datum })
      }
    );
  } else {
    blockBody = renderedBlock.children;
  }
  const alternate = renderedBlock.alternate ? /* @__PURE__ */ jsx(Box, { children: renderedBlock.alternate }) : void 0;
  const wrappedReference = /* @__PURE__ */ jsx(Entity, { accessor: referencedEntity, children: /* @__PURE__ */ jsx(ActionableBox, { editContents: alternate, onRemove, children: /* @__PURE__ */ jsx(
    FieldSet,
    {
      heading: renderedBlock.label,
      isActive: selected && !isEditable,
      onClick: isEditable ? onContainerClick : void 0,
      children: blockBody
    }
  ) }) });
  return /* @__PURE__ */ jsx(BlockElement, { element: props.element, attributes: props.attributes, withBoundaries: true, children: isEditable ? wrappedReference : (
    // https://github.com/ianstormtaylor/slate/issues/3426#issuecomment-573939245
    /* @__PURE__ */ jsxs(Fragment, { children: [
      /* @__PURE__ */ jsx(
        "div",
        {
          contentEditable: false,
          "data-slate-editor": false,
          style: isFullWidth ? void 0 : { display: "inline-block" },
          children: wrappedReference
        }
      ),
      props.children
    ] })
  ) });
});
ReferenceElementRenderer.displayName = "ReferenceElementRenderer";
function EmbedElementRendererInner({ handler }) {
  return /* @__PURE__ */ jsx(Fragment, { children: handler.renderEmbed() });
}
export {
  ReferenceElementRenderer
};
//# sourceMappingURL=ReferenceElementRenderer.js.map
