"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/components/grid/use-grid-layout-sync.js
var use_grid_layout_sync_exports = {};
__export(use_grid_layout_sync_exports, {
  useGridLayoutSync: () => useGridLayoutSync
});
module.exports = __toCommonJS(use_grid_layout_sync_exports);
var import_data = require("@wordpress/data");
var import_element = require("@wordpress/element");
var import_compose = require("@wordpress/compose");
var import_store = require("../../store");
var import_utils = require("./utils");
var import_object = require("../../utils/object");
function useGridLayoutSync({ clientId: gridClientId }) {
  const { gridLayout, blockOrder, selectedBlockLayout } = (0, import_data.useSelect)(
    (select) => {
      const { getBlockAttributes: getBlockAttributes2, getBlockOrder } = select(import_store.store);
      const selectedBlock = select(import_store.store).getSelectedBlock();
      return {
        gridLayout: getBlockAttributes2(gridClientId).layout ?? {},
        blockOrder: getBlockOrder(gridClientId),
        selectedBlockLayout: selectedBlock?.attributes.style?.layout
      };
    },
    [gridClientId]
  );
  const { getBlockAttributes, getBlockRootClientId } = (0, import_data.useSelect)(import_store.store);
  const { updateBlockAttributes, __unstableMarkNextChangeAsNotPersistent } = (0, import_data.useDispatch)(import_store.store);
  const selectedBlockRect = (0, import_element.useMemo)(
    () => selectedBlockLayout ? new import_utils.GridRect(selectedBlockLayout) : null,
    [selectedBlockLayout]
  );
  const previouslySelectedBlockRect = (0, import_compose.usePrevious)(selectedBlockRect);
  const previousIsManualPlacement = (0, import_compose.usePrevious)(
    gridLayout.isManualPlacement
  );
  const previousBlockOrder = (0, import_compose.usePrevious)(blockOrder);
  (0, import_element.useEffect)(() => {
    const updates = {};
    if (gridLayout.isManualPlacement) {
      const occupiedRects = [];
      for (const clientId of blockOrder) {
        const {
          columnStart,
          rowStart,
          columnSpan = 1,
          rowSpan = 1
        } = getBlockAttributes(clientId).style?.layout ?? {};
        if (!columnStart || !rowStart) {
          continue;
        }
        occupiedRects.push(
          new import_utils.GridRect({
            columnStart,
            rowStart,
            columnSpan,
            rowSpan
          })
        );
      }
      for (const clientId of blockOrder) {
        const attributes = getBlockAttributes(clientId);
        const {
          columnStart,
          rowStart,
          columnSpan = 1,
          rowSpan = 1
        } = attributes.style?.layout ?? {};
        if (columnStart && rowStart) {
          continue;
        }
        const [newColumnStart, newRowStart] = placeBlock(
          occupiedRects,
          gridLayout.columnCount,
          columnSpan,
          rowSpan,
          previouslySelectedBlockRect?.columnEnd,
          previouslySelectedBlockRect?.rowEnd
        );
        occupiedRects.push(
          new import_utils.GridRect({
            columnStart: newColumnStart,
            rowStart: newRowStart,
            columnSpan,
            rowSpan
          })
        );
        updates[clientId] = {
          style: {
            ...attributes.style,
            layout: {
              ...attributes.style?.layout,
              columnStart: newColumnStart,
              rowStart: newRowStart
            }
          }
        };
      }
      const bottomMostRow = Math.max(
        ...occupiedRects.map((r) => r.rowEnd)
      );
      if (!gridLayout.rowCount || gridLayout.rowCount < bottomMostRow) {
        updates[gridClientId] = {
          layout: {
            ...gridLayout,
            rowCount: bottomMostRow
          }
        };
      }
      for (const clientId of previousBlockOrder ?? []) {
        if (!blockOrder.includes(clientId)) {
          const rootClientId = getBlockRootClientId(clientId);
          if (rootClientId === null) {
            continue;
          }
          const rootAttributes = getBlockAttributes(rootClientId);
          if (rootAttributes?.layout?.type === "grid") {
            continue;
          }
          const attributes = getBlockAttributes(clientId);
          const {
            columnStart,
            rowStart,
            columnSpan,
            rowSpan,
            ...layout
          } = attributes.style?.layout ?? {};
          if (columnStart || rowStart || columnSpan || rowSpan) {
            const hasEmptyLayoutAttribute = Object.keys(layout).length === 0;
            updates[clientId] = (0, import_object.setImmutably)(
              attributes,
              ["style", "layout"],
              hasEmptyLayoutAttribute ? void 0 : layout
            );
          }
        }
      }
    } else {
      if (previousIsManualPlacement === true) {
        for (const clientId of blockOrder) {
          const attributes = getBlockAttributes(clientId);
          const { columnStart, rowStart, ...layout } = attributes.style?.layout ?? {};
          if (columnStart || rowStart) {
            const hasEmptyLayoutAttribute = Object.keys(layout).length === 0;
            updates[clientId] = (0, import_object.setImmutably)(
              attributes,
              ["style", "layout"],
              hasEmptyLayoutAttribute ? void 0 : layout
            );
          }
        }
      }
      if (gridLayout.rowCount) {
        updates[gridClientId] = {
          layout: {
            ...gridLayout,
            rowCount: void 0
          }
        };
      }
    }
    if (Object.keys(updates).length) {
      __unstableMarkNextChangeAsNotPersistent();
      updateBlockAttributes(
        Object.keys(updates),
        updates,
        /* uniqueByBlock: */
        true
      );
    }
  }, [
    // Actual deps to sync:
    gridClientId,
    gridLayout,
    previousBlockOrder,
    blockOrder,
    previouslySelectedBlockRect,
    previousIsManualPlacement,
    // These won't change, but the linter thinks they might:
    __unstableMarkNextChangeAsNotPersistent,
    getBlockAttributes,
    getBlockRootClientId,
    updateBlockAttributes
  ]);
}
function placeBlock(occupiedRects, gridColumnCount, blockColumnSpan, blockRowSpan, startColumn = 1, startRow = 1) {
  for (let row = startRow; ; row++) {
    for (let column = row === startRow ? startColumn : 1; column <= gridColumnCount; column++) {
      const candidateRect = new import_utils.GridRect({
        columnStart: column,
        rowStart: row,
        columnSpan: blockColumnSpan,
        rowSpan: blockRowSpan
      });
      if (!occupiedRects.some(
        (r) => r.intersectsRect(candidateRect)
      )) {
        return [column, row];
      }
    }
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  useGridLayoutSync
});
//# sourceMappingURL=use-grid-layout-sync.js.map
