// packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
import { useDispatch, useRegistry, useSelect } from "@wordpress/data";
import { isUnmodifiedDefaultBlock } from "@wordpress/blocks";
import { _n, sprintf } from "@wordpress/i18n";
import { speak } from "@wordpress/a11y";
import { useCallback } from "@wordpress/element";
import { store as blockEditorStore } from "../../../store";
import { unlock } from "../../../lock-unlock";
function getIndex({
  destinationRootClientId,
  destinationIndex,
  rootClientId,
  registry
}) {
  if (rootClientId === destinationRootClientId) {
    return destinationIndex;
  }
  const parents = [
    "",
    ...registry.select(blockEditorStore).getBlockParents(destinationRootClientId),
    destinationRootClientId
  ];
  const parentIndex = parents.indexOf(rootClientId);
  if (parentIndex !== -1) {
    return registry.select(blockEditorStore).getBlockIndex(parents[parentIndex + 1]) + 1;
  }
  return registry.select(blockEditorStore).getBlockOrder(rootClientId).length;
}
function useInsertionPoint({
  rootClientId = "",
  insertionIndex,
  clientId,
  isAppender,
  onSelect,
  shouldFocusBlock = true,
  selectBlockOnInsert = true
}) {
  const registry = useRegistry();
  const {
    getSelectedBlock,
    getClosestAllowedInsertionPoint,
    isBlockInsertionPointVisible
  } = unlock(useSelect(blockEditorStore));
  const { destinationRootClientId, destinationIndex } = useSelect(
    (select) => {
      const {
        getSelectedBlockClientId,
        getBlockRootClientId,
        getBlockIndex,
        getBlockOrder,
        getInsertionPoint
      } = unlock(select(blockEditorStore));
      const selectedBlockClientId = getSelectedBlockClientId();
      let _destinationRootClientId = rootClientId;
      let _destinationIndex;
      const insertionPoint = getInsertionPoint();
      if (insertionIndex !== void 0) {
        _destinationIndex = insertionIndex;
      } else if (insertionPoint && insertionPoint.hasOwnProperty("index")) {
        _destinationRootClientId = insertionPoint?.rootClientId ? insertionPoint.rootClientId : rootClientId;
        _destinationIndex = insertionPoint.index;
      } else if (clientId) {
        _destinationIndex = getBlockIndex(clientId);
      } else if (!isAppender && selectedBlockClientId) {
        _destinationRootClientId = getBlockRootClientId(
          selectedBlockClientId
        );
        _destinationIndex = getBlockIndex(selectedBlockClientId) + 1;
      } else {
        _destinationIndex = getBlockOrder(
          _destinationRootClientId
        ).length;
      }
      return {
        destinationRootClientId: _destinationRootClientId,
        destinationIndex: _destinationIndex
      };
    },
    [rootClientId, insertionIndex, clientId, isAppender]
  );
  const {
    replaceBlocks,
    insertBlocks,
    showInsertionPoint,
    hideInsertionPoint,
    setLastFocus
  } = unlock(useDispatch(blockEditorStore));
  const onInsertBlocks = useCallback(
    (blocks, meta, shouldForceFocusBlock = false, _rootClientId) => {
      if (shouldForceFocusBlock || shouldFocusBlock || selectBlockOnInsert) {
        setLastFocus(null);
      }
      const selectedBlock = getSelectedBlock();
      if (!isAppender && selectedBlock && isUnmodifiedDefaultBlock(selectedBlock, "content")) {
        replaceBlocks(
          selectedBlock.clientId,
          blocks,
          null,
          shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
          meta
        );
      } else {
        insertBlocks(
          blocks,
          isAppender || _rootClientId === void 0 ? destinationIndex : getIndex({
            destinationRootClientId,
            destinationIndex,
            rootClientId: _rootClientId,
            registry
          }),
          isAppender || _rootClientId === void 0 ? destinationRootClientId : _rootClientId,
          selectBlockOnInsert,
          shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
          meta
        );
      }
      const blockLength = Array.isArray(blocks) ? blocks.length : 1;
      const message = sprintf(
        // translators: %d: the name of the block that has been added
        _n("%d block added.", "%d blocks added.", blockLength),
        blockLength
      );
      speak(message);
      if (onSelect) {
        onSelect(blocks);
      }
    },
    [
      isAppender,
      getSelectedBlock,
      replaceBlocks,
      insertBlocks,
      destinationRootClientId,
      destinationIndex,
      onSelect,
      shouldFocusBlock,
      selectBlockOnInsert
    ]
  );
  const onToggleInsertionPoint = useCallback(
    (item) => {
      if (item && !isBlockInsertionPointVisible()) {
        const allowedDestinationRootClientId = getClosestAllowedInsertionPoint(
          item.name,
          destinationRootClientId
        );
        if (allowedDestinationRootClientId !== null) {
          showInsertionPoint(
            allowedDestinationRootClientId,
            getIndex({
              destinationRootClientId,
              destinationIndex,
              rootClientId: allowedDestinationRootClientId,
              registry
            })
          );
        }
      } else {
        hideInsertionPoint();
      }
    },
    [
      getClosestAllowedInsertionPoint,
      isBlockInsertionPointVisible,
      showInsertionPoint,
      hideInsertionPoint,
      destinationRootClientId,
      destinationIndex
    ]
  );
  return [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint];
}
var use_insertion_point_default = useInsertionPoint;
export {
  use_insertion_point_default as default
};
//# sourceMappingURL=use-insertion-point.js.map
