import { useDebounceCallback } from "@contember/react-utils";
import { useReducer, useRef, useCallback, useEffect } from "react";
import { Range, Editor } from "slate";
import { useSlateStatic, ReactEditor } from "slate-react";
import { editorSelectionReducer, defaultEditorSelectionState } from "./editorSelectionReducer.js";
const useEditorSelection = (maxInterval = 100) => {
  const editor = useSlateStatic();
  const [selectionState, dispatch] = useReducer(editorSelectionReducer, defaultEditorSelectionState);
  const selectionStateRef = useRef(selectionState);
  selectionStateRef.current = selectionState;
  const onDOMSelectionChange = useDebounceCallback(
    useCallback(() => {
      const domSelection = getSelection();
      const isRelevant = domSelection && domSelection.anchorNode && ReactEditor.hasDOMNode(editor, domSelection.anchorNode, { editable: true });
      if (isRelevant) {
        if ((selectionStateRef.current.name === "expandedPointerSelection" || selectionStateRef.current.name === "expandedNonPointerSelection") && !domSelection.isCollapsed && selectionStateRef.current.selection) {
          const stateSelectionRange = ReactEditor.toSlateRange(editor, selectionStateRef.current.selection, { exactMatch: false, suppressThrow: false });
          const domSelectionRange = ReactEditor.toSlateRange(editor, domSelection, { exactMatch: false, suppressThrow: false });
          if (Range.equals(stateSelectionRange, domSelectionRange) && (!editor.selection || Editor.string(editor, editor.selection) === selectionStateRef.current.selectedString)) {
            return;
          }
        }
        dispatch({
          type: "setSelection",
          selection: domSelection
        });
      } else {
        dispatch({
          type: "blur"
        });
      }
    }, [editor]),
    maxInterval
  );
  const onMouseDown = useCallback(
    (e) => {
      e.target && e.target instanceof Node && ReactEditor.hasDOMNode(editor, e.target) && dispatch({
        type: "setMousePointerSelectionStart",
        event: e
      });
    },
    [editor]
  );
  const onMouseUp = useCallback(
    (e) => {
      const relevantTarget = !!e.target && e.target instanceof Node && ReactEditor.hasDOMNode(editor, e.target);
      dispatch({
        type: "setMousePointerSelectionFinish",
        event: relevantTarget ? e : void 0
      });
    },
    [editor]
  );
  useEffect(() => {
    document.addEventListener("selectionchange", onDOMSelectionChange);
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mouseup", onMouseUp);
    return () => {
      document.removeEventListener("selectionchange", onDOMSelectionChange);
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("mouseup", onMouseUp);
    };
  }, [onDOMSelectionChange, onMouseDown, onMouseUp]);
  return selectionState;
};
export {
  useEditorSelection
};
//# sourceMappingURL=useEditorSelection.js.map
