import { memo, useCallback, createElement, Fragment } from "react";
import { useEntity, BindingError, Entity } from "@contember/binding";
import { EditorPlaceholder, Box, ActionableBox, FieldSet } from "@contember/ui";
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__ */ createElement(Fragment, null, !!contentTemplate.nodeBefore && /* @__PURE__ */ createElement("div", {
      contentEditable: false
    }, contentTemplate.nodeBefore), showPlaceholder ? /* @__PURE__ */ createElement("div", {
      style: { position: "relative" }
    }, /* @__PURE__ */ createElement("div", {
      style: { position: "absolute", pointerEvents: "none" }
    }, /* @__PURE__ */ createElement(EditorPlaceholder, null, placeholder)), /* @__PURE__ */ createElement("div", null, props.children)) : /* @__PURE__ */ createElement("div", null, props.children), !!contentTemplate.nodeAfter && /* @__PURE__ */ createElement("div", {
      contentEditable: false
    }, 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__ */ createElement("div", {
      style: { display: "flex" }
    }, /* @__PURE__ */ createElement(EmbedElementRendererInner, {
      handler: embedHandler.datum
    }));
  } else {
    blockBody = renderedBlock.children;
  }
  const alternate = renderedBlock.alternate ? /* @__PURE__ */ createElement(Box, null, renderedBlock.alternate) : void 0;
  const wrappedReference = /* @__PURE__ */ createElement(Entity, {
    accessor: referencedEntity
  }, /* @__PURE__ */ createElement(ActionableBox, {
    editContents: alternate,
    onRemove
  }, /* @__PURE__ */ createElement(FieldSet, {
    heading: renderedBlock.label,
    isActive: selected && !isEditable,
    onClick: isEditable ? onContainerClick : void 0
  }, blockBody)));
  return /* @__PURE__ */ createElement(BlockElement, {
    element: props.element,
    attributes: props.attributes,
    withBoundaries: true
  }, isEditable ? wrappedReference : /* @__PURE__ */ createElement(Fragment, null, /* @__PURE__ */ createElement("div", {
    contentEditable: false,
    "data-slate-editor": false,
    style: isFullWidth ? void 0 : { display: "inline-block" }
  }, wrappedReference), props.children));
});
ReferenceElementRenderer.displayName = "ReferenceElementRenderer";
function EmbedElementRendererInner({ handler }) {
  return /* @__PURE__ */ createElement(Fragment, null, handler.renderEmbed());
}
export { ReferenceElementRenderer };
//# sourceMappingURL=ReferenceElementRenderer.js.map
