// packages/block-editor/src/components/block-draggable/index.js
import { store as blocksStore } from "@wordpress/blocks";
import { Draggable } from "@wordpress/components";
import { useSelect, useDispatch } from "@wordpress/data";
import { useEffect, useRef } from "@wordpress/element";
import { throttle } from "@wordpress/compose";
import BlockDraggableChip from "./draggable-chip";
import useScrollWhenDragging from "./use-scroll-when-dragging";
import { store as blockEditorStore } from "../../store";
import { useBlockElement } from "../block-list/use-block-props/use-block-refs";
import { isDropTargetValid } from "../use-block-drop-zone";
import { jsx } from "react/jsx-runtime";
var BlockDraggable = ({
  appendToOwnerDocument,
  children,
  clientIds,
  cloneClassname,
  elementId,
  onDragStart,
  onDragEnd,
  fadeWhenDisabled = false,
  dragComponent
}) => {
  const {
    srcRootClientId,
    isDraggable,
    icon,
    visibleInserter,
    getBlockType
  } = useSelect(
    (select) => {
      const {
        canMoveBlocks,
        getBlockRootClientId: getBlockRootClientId2,
        getBlockName,
        getBlockAttributes,
        isBlockInsertionPointVisible
      } = select(blockEditorStore);
      const { getBlockType: _getBlockType, getActiveBlockVariation } = select(blocksStore);
      const rootClientId = getBlockRootClientId2(clientIds[0]);
      const blockName = getBlockName(clientIds[0]);
      const variation = getActiveBlockVariation(
        blockName,
        getBlockAttributes(clientIds[0])
      );
      return {
        srcRootClientId: rootClientId,
        isDraggable: canMoveBlocks(clientIds),
        icon: variation?.icon || _getBlockType(blockName)?.icon,
        visibleInserter: isBlockInsertionPointVisible(),
        getBlockType: _getBlockType
      };
    },
    [clientIds]
  );
  const isDraggingRef = useRef(false);
  const [startScrolling, scrollOnDragOver, stopScrolling] = useScrollWhenDragging();
  const { getAllowedBlocks, getBlockNamesByClientId, getBlockRootClientId } = useSelect(blockEditorStore);
  const { startDraggingBlocks, stopDraggingBlocks } = useDispatch(blockEditorStore);
  useEffect(() => {
    return () => {
      if (isDraggingRef.current) {
        stopDraggingBlocks();
      }
    };
  }, []);
  const blockEl = useBlockElement(clientIds[0]);
  const editorRoot = blockEl?.closest("body");
  useEffect(() => {
    if (!editorRoot || !fadeWhenDisabled) {
      return;
    }
    const onDragOver = (event) => {
      if (!event.target.closest("[data-block]")) {
        return;
      }
      const draggedBlockNames = getBlockNamesByClientId(clientIds);
      const targetClientId = event.target.closest("[data-block]").getAttribute("data-block");
      const allowedBlocks = getAllowedBlocks(targetClientId);
      const targetBlockName = getBlockNamesByClientId([
        targetClientId
      ])[0];
      let dropTargetValid;
      if (allowedBlocks?.length === 0) {
        const targetRootClientId = getBlockRootClientId(targetClientId);
        const targetRootBlockName = getBlockNamesByClientId([
          targetRootClientId
        ])[0];
        const rootAllowedBlocks = getAllowedBlocks(targetRootClientId);
        dropTargetValid = isDropTargetValid(
          getBlockType,
          rootAllowedBlocks,
          draggedBlockNames,
          targetRootBlockName
        );
      } else {
        dropTargetValid = isDropTargetValid(
          getBlockType,
          allowedBlocks,
          draggedBlockNames,
          targetBlockName
        );
      }
      if (!dropTargetValid && !visibleInserter) {
        window?.document?.body?.classList?.add(
          "block-draggable-invalid-drag-token"
        );
      } else {
        window?.document?.body?.classList?.remove(
          "block-draggable-invalid-drag-token"
        );
      }
    };
    const throttledOnDragOver = throttle(onDragOver, 200);
    editorRoot.addEventListener("dragover", throttledOnDragOver);
    return () => {
      editorRoot.removeEventListener("dragover", throttledOnDragOver);
    };
  }, [
    clientIds,
    editorRoot,
    fadeWhenDisabled,
    getAllowedBlocks,
    getBlockNamesByClientId,
    getBlockRootClientId,
    getBlockType,
    visibleInserter
  ]);
  if (!isDraggable) {
    return children({ draggable: false });
  }
  const transferData = {
    type: "block",
    srcClientIds: clientIds,
    srcRootClientId
  };
  return /* @__PURE__ */ jsx(
    Draggable,
    {
      appendToOwnerDocument,
      cloneClassname,
      __experimentalTransferDataType: "wp-blocks",
      transferData,
      onDragStart: (event) => {
        window.requestAnimationFrame(() => {
          startDraggingBlocks(clientIds);
          isDraggingRef.current = true;
          startScrolling(event);
          if (onDragStart) {
            onDragStart();
          }
        });
      },
      onDragOver: scrollOnDragOver,
      onDragEnd: () => {
        stopDraggingBlocks();
        isDraggingRef.current = false;
        stopScrolling();
        if (onDragEnd) {
          onDragEnd();
        }
      },
      __experimentalDragComponent: (
        // Check against `undefined` so that `null` can be used to disable
        // the default drag component.
        dragComponent !== void 0 ? dragComponent : /* @__PURE__ */ jsx(
          BlockDraggableChip,
          {
            count: clientIds.length,
            icon,
            fadeWhenDisabled: true
          }
        )
      ),
      elementId,
      children: ({ onDraggableStart, onDraggableEnd }) => {
        return children({
          draggable: true,
          onDragStart: onDraggableStart,
          onDragEnd: onDraggableEnd
        });
      }
    }
  );
};
var block_draggable_default = BlockDraggable;
export {
  block_draggable_default as default
};
//# sourceMappingURL=index.js.map
