// packages/block-editor/src/hooks/block-hooks.js
import { __ } from "@wordpress/i18n";
import { Fragment, useMemo } from "@wordpress/element";
import { PanelBody, ToggleControl } from "@wordpress/components";
import { createBlock, store as blocksStore } from "@wordpress/blocks";
import { useDispatch, useSelect } from "@wordpress/data";
import { InspectorControls } from "../components";
import { store as blockEditorStore } from "../store";
import { jsx, jsxs } from "react/jsx-runtime";
var EMPTY_OBJECT = {};
function BlockHooksControlPure({
  name,
  clientId,
  metadata: { ignoredHookedBlocks = [] } = {}
}) {
  const blockTypes = useSelect(
    (select) => select(blocksStore).getBlockTypes(),
    []
  );
  const hookedBlocksForCurrentBlock = useMemo(
    () => blockTypes?.filter(
      ({ name: blockName, blockHooks }) => blockHooks && name in blockHooks || ignoredHookedBlocks.includes(blockName)
    ),
    [blockTypes, name, ignoredHookedBlocks]
  );
  const hookedBlockClientIds = useSelect(
    (select) => {
      const { getBlocks, getBlockRootClientId: getBlockRootClientId2, getGlobalBlockCount } = select(blockEditorStore);
      const rootClientId = getBlockRootClientId2(clientId);
      const _hookedBlockClientIds = hookedBlocksForCurrentBlock.reduce(
        (clientIds, block) => {
          if (getGlobalBlockCount(block.name) === 0) {
            return clientIds;
          }
          const relativePosition = block?.blockHooks?.[name];
          let candidates;
          switch (relativePosition) {
            case "before":
            case "after":
              candidates = getBlocks(rootClientId);
              break;
            case "first_child":
            case "last_child":
              candidates = getBlocks(clientId);
              break;
            case void 0:
              candidates = [
                ...getBlocks(rootClientId),
                ...getBlocks(clientId)
              ];
              break;
          }
          const hookedBlock = candidates?.find(
            (candidate) => candidate.name === block.name
          );
          if (hookedBlock) {
            return {
              ...clientIds,
              [block.name]: hookedBlock.clientId
            };
          }
          return clientIds;
        },
        {}
      );
      if (Object.values(_hookedBlockClientIds).length > 0) {
        return _hookedBlockClientIds;
      }
      return EMPTY_OBJECT;
    },
    [hookedBlocksForCurrentBlock, name, clientId]
  );
  const { getBlockIndex, getBlockCount, getBlockRootClientId } = useSelect(blockEditorStore);
  const { insertBlock, removeBlock } = useDispatch(blockEditorStore);
  if (!hookedBlocksForCurrentBlock.length) {
    return null;
  }
  const groupedHookedBlocks = hookedBlocksForCurrentBlock.reduce(
    (groups, block) => {
      const [namespace] = block.name.split("/");
      if (!groups[namespace]) {
        groups[namespace] = [];
      }
      groups[namespace].push(block);
      return groups;
    },
    {}
  );
  const insertBlockIntoDesignatedLocation = (block, relativePosition) => {
    const blockIndex = getBlockIndex(clientId);
    const innerBlocksLength = getBlockCount(clientId);
    const rootClientId = getBlockRootClientId(clientId);
    switch (relativePosition) {
      case "before":
      case "after":
        insertBlock(
          block,
          relativePosition === "after" ? blockIndex + 1 : blockIndex,
          rootClientId,
          // Insert as a child of the current block's parent
          false
        );
        break;
      case "first_child":
      case "last_child":
        insertBlock(
          block,
          // TODO: It'd be great if insertBlock() would accept negative indices for insertion.
          relativePosition === "first_child" ? 0 : innerBlocksLength,
          clientId,
          // Insert as a child of the current block.
          false
        );
        break;
      case void 0:
        insertBlock(
          block,
          blockIndex + 1,
          rootClientId,
          // Insert as a child of the current block's parent
          false
        );
        break;
    }
  };
  return /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsxs(
    PanelBody,
    {
      className: "block-editor-hooks__block-hooks",
      title: __("Plugins"),
      initialOpen: true,
      children: [
        /* @__PURE__ */ jsx("p", { className: "block-editor-hooks__block-hooks-helptext", children: __(
          "Manage the inclusion of blocks added automatically by plugins."
        ) }),
        Object.keys(groupedHookedBlocks).map((vendor) => {
          return /* @__PURE__ */ jsxs(Fragment, { children: [
            /* @__PURE__ */ jsx("h3", { children: vendor }),
            groupedHookedBlocks[vendor].map((block) => {
              const checked = block.name in hookedBlockClientIds;
              return /* @__PURE__ */ jsx(
                ToggleControl,
                {
                  __nextHasNoMarginBottom: true,
                  checked,
                  label: block.title,
                  onChange: () => {
                    if (!checked) {
                      const relativePosition = block.blockHooks[name];
                      insertBlockIntoDesignatedLocation(
                        createBlock(block.name),
                        relativePosition
                      );
                      return;
                    }
                    removeBlock(
                      hookedBlockClientIds[block.name],
                      false
                    );
                  }
                },
                block.title
              );
            })
          ] }, vendor);
        })
      ]
    }
  ) });
}
var block_hooks_default = {
  edit: BlockHooksControlPure,
  attributeKeys: ["metadata"],
  hasSupport() {
    return true;
  }
};
export {
  block_hooks_default as default
};
//# sourceMappingURL=block-hooks.js.map
