import { Fragment, jsx } from "react/jsx-runtime";
import { cx } from "@emotion/css";
import { Editor, Transforms, Range, Node, Text } from "slate";
import { Select, Slate } from "@makeswift/controls";
import { setBlockKeyForDevice } from "./setBlockKeyForDevice";
import { clearBlockKeyForDevice } from "./clearBlockKeyForDevice";
import { wrapInline } from "./wrapInline";
import { unwrapInline } from "./unwrapInline";
import { getSelection } from "../selectors";
import { ElementUtils } from "../utils/element";
import { getActiveBlockType } from "../selectors";
import { unwrapList } from "./unwrapList";
import { wrapList } from "./wrapList";
import { indent } from "./indent";
import { dedent } from "./dedent";
import { toggleList } from "./toggleList";
import { EditorUtils } from "../utils/editor";
import isHotkey from "is-hotkey";
import { LIST_ITEM_CHILD_POSITION } from "./constants";
import { useStyle } from "../../runtimes/react/use-style";
import { Plugin } from "../../controls/rich-text-v2/plugin";
import { BlockType } from "../../slate/types";
const BlockActions = {
  setBlockKeyForDevice,
  clearBlockKeyForDevice,
  wrapInline,
  unwrapInline
};
const ListActions = {
  unwrapList,
  wrapList,
  indent,
  dedent,
  toggleList
};
function onKeyDown(e, editor) {
  if (!editor.selection || Array.from(Editor.nodes(editor, { match: (node) => Slate.isListItem(node) })).length === 0)
    return;
  if (isHotkey("shift+tab", e)) {
    e.preventDefault();
    ListActions.dedent(editor);
  }
  if (isHotkey("tab", e)) {
    e.preventDefault();
    ListActions.indent(editor);
  }
  if (isHotkey("backspace", e)) {
    if (!editor.selection)
      return;
    if (Range.isExpanded(editor.selection))
      return;
    const listItem = EditorUtils.getFirstAncestorListItem(editor, editor.selection.anchor.path);
    if (editor.selection.anchor.offset === 0 && listItem) {
      e.preventDefault();
      const parentListItem = EditorUtils.getFirstAncestorListItem(editor, listItem[1]);
      const list = EditorUtils.getFirstAncestorList(editor, listItem[1]);
      if (parentListItem) {
        ListActions.dedent(editor);
      } else if (list) {
        ListActions.unwrapList(editor);
      }
      return;
    }
  }
  if (isHotkey("enter", e)) {
    e.preventDefault();
    if (!editor.selection)
      return;
    if (Range.isExpanded(editor.selection)) {
      Transforms.delete(editor);
      return;
    }
    const listItem = EditorUtils.getFirstAncestorListItem(editor, editor.selection.anchor.path);
    if (editor.selection.anchor.offset === 0 && listItem && Editor.string(editor, listItem[1]) === "") {
      const parentListItem = EditorUtils.getFirstAncestorListItem(editor, listItem[1]);
      if (parentListItem) {
        ListActions.dedent(editor);
      } else {
        ListActions.unwrapList(editor);
      }
      return;
    }
    Transforms.splitNodes(editor, {
      at: editor.selection,
      always: true,
      match: (node) => Slate.isListItem(node)
    });
  }
  if (isHotkey("shift+enter", e)) {
    e.preventDefault();
    editor.insertText("\n");
  }
}
function withBlock(editor) {
  const { normalizeNode } = editor;
  editor.isInline = (entry) => {
    return Slate.isInline(entry);
  };
  editor.normalizeNode = (entry) => {
    const [normalizationNode, normalizationPath] = entry;
    if (Slate.isBlock(normalizationNode) && normalizationNode?.textAlign?.length == 0) {
      Transforms.unsetNodes(editor, "textAlign", { at: normalizationPath });
      return;
    }
    if (normalizationPath.length === 1 && Slate.isRootBlock(normalizationNode) && !Slate.isList(normalizationNode)) {
      const children = Array.from(Node.children(editor, normalizationPath));
      if (children.findIndex(([child]) => Slate.isRootBlock(child)) !== -1) {
        Transforms.unwrapNodes(editor, { at: normalizationPath });
        return;
      }
    }
    if (Slate.isListItem(normalizationNode)) {
      const pathToListItemText = [...normalizationPath, LIST_ITEM_CHILD_POSITION];
      if (Node.has(editor, pathToListItemText)) {
        const nodeInListItemTextPosition = Node.get(editor, pathToListItemText);
        if (Slate.isRootBlock(nodeInListItemTextPosition)) {
          Transforms.setNodes(
            editor,
            { type: BlockType.ListItemChild },
            {
              at: pathToListItemText
            }
          );
          return;
        }
      } else {
        Transforms.insertNodes(editor, ElementUtils.createListItem(), {
          at: pathToListItemText
        });
        return;
      }
    }
    if (!Text.isText(normalizationNode)) {
      const mergeableChildren = Array.from(Node.children(editor, normalizationPath)).map((child, index, children) => {
        const potentialNodeToBeMerged = children.at(index + 1);
        if (!potentialNodeToBeMerged || !Slate.isList(potentialNodeToBeMerged[0]) || !Slate.isList(child[0]) || potentialNodeToBeMerged[0].type !== child[0].type) {
          return null;
        }
        return [
          Editor.pathRef(editor, child[1]),
          Editor.pathRef(editor, potentialNodeToBeMerged[1])
        ];
      }).filter((mergeableNodes) => Boolean(mergeableNodes));
      if (mergeableChildren.length !== 0) {
        mergeableChildren.reverse().forEach(([nodePathRef, nodeToBeMergedPathRef]) => {
          const nodePath = nodePathRef.current;
          const nodeToBeMergedPath = nodeToBeMergedPathRef.current;
          if (nodePath == null || nodeToBeMergedPath == null)
            return;
          const nodeChildren = Array.from(Node.children(editor, nodePath));
          const childrenToBeMerged = Array.from(Node.children(editor, nodeToBeMergedPath));
          Editor.withoutNormalizing(editor, () => {
            childrenToBeMerged.reverse().forEach(([_, childPath]) => {
              Transforms.moveNodes(editor, {
                at: childPath,
                to: [...nodePath, nodeChildren.length]
              });
            });
            Transforms.removeNodes(editor, { at: nodeToBeMergedPath });
          });
          nodePathRef.unref();
          nodeToBeMergedPathRef.unref();
        });
        return;
      }
    }
    normalizeNode(entry);
  };
  return editor;
}
const definition = Select({
  label: "Block",
  labelOrientation: "horizontal",
  options: [
    {
      value: BlockType.Paragraph,
      label: "Paragraph"
    },
    {
      value: BlockType.Heading1,
      label: "Heading 1"
    },
    {
      value: BlockType.Heading2,
      label: "Heading 2"
    },
    {
      value: BlockType.Heading3,
      label: "Heading 3"
    },
    {
      value: BlockType.Heading4,
      label: "Heading 4"
    },
    {
      value: BlockType.Heading5,
      label: "Heading 5"
    },
    {
      value: BlockType.Heading6,
      label: "Heading 6"
    },
    {
      value: BlockType.UnorderedList,
      label: "Bulleted list"
    },
    {
      value: BlockType.OrderedList,
      label: "Numbered list"
    },
    {
      value: BlockType.BlockQuote,
      label: "Quote"
    }
  ],
  defaultValue: BlockType.Paragraph
});
function BlockPlugin() {
  return Plugin({
    withPlugin: withBlock,
    onKeyDown,
    control: {
      definition,
      onChange: (editor, value) => {
        const activeBlockType = getActiveBlockType(editor);
        if (value === BlockType.UnorderedList || value === BlockType.OrderedList) {
          ListActions.toggleList(editor, {
            type: value,
            at: getSelection(editor)
          });
        } else if (activeBlockType === value) {
          Transforms.setNodes(
            editor,
            {
              type: BlockType.Default
            },
            { at: getSelection(editor) }
          );
        } else {
          ListActions.unwrapList(editor, {
            at: getSelection(editor)
          });
          Transforms.setNodes(
            editor,
            {
              type: value ?? BlockType.Default
            },
            { at: getSelection(editor) }
          );
        }
      },
      getValue: (editor) => {
        const activeBlock = getActiveBlockType(editor);
        if (activeBlock == null)
          return void 0;
        if (activeBlock === Slate.RootBlockType.Default)
          return void 0;
        return activeBlock;
      }
    },
    renderElement: (renderElement) => (props) => /* @__PURE__ */ jsx(BlockPluginComponent, { ...props, renderElement })
  });
}
function BlockPluginComponent({
  renderElement,
  ...props
}) {
  const blockStyles = [useStyle({ margin: 0 }), props.element.className];
  const quoteStyles = useStyle({
    padding: "0.5em 10px",
    fontSize: "1.25em",
    fontWeight: "300",
    borderLeft: "5px solid rgba(0, 0, 0, 0.1)"
  });
  const unorderedListStyles = useStyle({
    listStylePosition: "inside",
    paddingInlineStart: "20px",
    listStyleType: "disc",
    ul: {
      listStyleType: "circle"
    },
    "ul ul": {
      listStyleType: "square"
    }
  });
  const orderedListStyles = useStyle({
    listStylePosition: "inside",
    paddingInlineStart: "20px",
    listStyleType: "decimal"
  });
  switch (props.element.type) {
    case BlockType.Default:
    case BlockType.Paragraph:
      return /* @__PURE__ */ jsx("p", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading1:
      return /* @__PURE__ */ jsx("h1", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading2:
      return /* @__PURE__ */ jsx("h2", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading3:
      return /* @__PURE__ */ jsx("h3", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading4:
      return /* @__PURE__ */ jsx("h4", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading5:
      return /* @__PURE__ */ jsx("h5", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.Heading6:
      return /* @__PURE__ */ jsx("h6", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.BlockQuote:
      return /* @__PURE__ */ jsx("blockquote", { ...props.attributes, className: cx(...blockStyles, quoteStyles), children: renderElement(props) });
    case BlockType.OrderedList:
      return /* @__PURE__ */ jsx("ol", { ...props.attributes, className: cx(...blockStyles, orderedListStyles), children: renderElement(props) });
    case BlockType.UnorderedList:
      return /* @__PURE__ */ jsx("ul", { ...props.attributes, className: cx(...blockStyles, unorderedListStyles), children: renderElement(props) });
    case BlockType.ListItem:
      return /* @__PURE__ */ jsx("li", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    case BlockType.ListItemChild:
      return /* @__PURE__ */ jsx("span", { ...props.attributes, className: cx(...blockStyles), children: renderElement(props) });
    default:
      return /* @__PURE__ */ jsx(Fragment, { children: renderElement(props) });
  }
}
export {
  BlockActions,
  BlockPlugin,
  ListActions,
  onKeyDown,
  withBlock
};
//# sourceMappingURL=index.js.map