import React, { useRef, useEffect } from 'react';
import ReactGridLayout from 'react-grid-layout';
import { GRID_CELL_HEIGHT, GRID_COLUMN_COUNT, GRID_CELL_VMARGIN } from './constants.js';
import { LazyLoader } from '../LazyLoader.js';
import { useStyles2 } from '@grafana/ui';
import { css, cx } from '@emotion/css';
import { useMeasure } from 'react-use';

function SceneGridLayoutRenderer({ model }) {
  const { children, isLazy, isDraggable, isResizable } = model.useState();
  const [outerDivRef, { width, height }] = useMeasure();
  const ref = useRef(null);
  useEffect(() => {
    updateAnimationClass(ref, !!isDraggable);
  }, [isDraggable]);
  validateChildrenSize(children);
  const renderGrid = (width2, height2) => {
    if (!width2 || !height2) {
      return null;
    }
    const layout = model.buildGridLayout(width2, height2);
    return (
      /**
       * The children is using a width of 100% so we need to guarantee that it is wrapped
       * in an element that has the calculated size given by the AutoSizer. The AutoSizer
       * has a width of 0 and will let its content overflow its div.
       */
      /* @__PURE__ */ React.createElement(
        "div",
        {
          ref,
          style: { width: `${width2}px`, height: layout.length > 0 ? "100%" : "0" },
          className: "react-grid-layout"
        },
        /* @__PURE__ */ React.createElement(
          ReactGridLayout,
          {
            width: width2,
            isDraggable: isDraggable && width2 > 768,
            isResizable: isResizable != null ? isResizable : false,
            containerPadding: [0, 0],
            useCSSTransforms: true,
            margin: [GRID_CELL_VMARGIN, GRID_CELL_VMARGIN],
            cols: GRID_COLUMN_COUNT,
            rowHeight: GRID_CELL_HEIGHT,
            draggableHandle: `.grid-drag-handle-${model.state.key}`,
            draggableCancel: ".grid-drag-cancel",
            layout,
            onDragStart: model.onDragStart,
            onDragStop: model.onDragStop,
            onResizeStop: model.onResizeStop,
            onLayoutChange: model.onLayoutChange,
            isBounded: false,
            resizeHandle: /* @__PURE__ */ React.createElement(ResizeHandle, null)
          },
          layout.map((gridItem, index) => /* @__PURE__ */ React.createElement(
            GridItemWrapper,
            {
              key: gridItem.i,
              grid: model,
              layoutItem: gridItem,
              index,
              isLazy,
              totalCount: layout.length
            }
          ))
        )
      )
    );
  };
  return /* @__PURE__ */ React.createElement("div", { ref: outerDivRef, className: gridWrapperClass }, renderGrid(width, height));
}
const gridWrapperClass = css({
  flex: "1 1 auto",
  position: "relative",
  zIndex: 1,
  width: "100%"
});
const GridItemWrapper = React.forwardRef((props, ref) => {
  var _a;
  const { grid, layoutItem, index, totalCount, isLazy, style, onLoad, onChange, children, ...divProps } = props;
  const sceneChild = grid.getSceneLayoutChild(layoutItem.i);
  const className = (_a = sceneChild.getClassName) == null ? void 0 : _a.call(sceneChild);
  const innerContent = /* @__PURE__ */ React.createElement(sceneChild.Component, { model: sceneChild, key: sceneChild.state.key });
  if (isLazy) {
    return /* @__PURE__ */ React.createElement(
      LazyLoader,
      {
        ...divProps,
        key: sceneChild.state.key,
        "data-griditem-key": sceneChild.state.key,
        className: cx(className, props.className),
        style,
        ref
      },
      innerContent,
      children
    );
  }
  return /* @__PURE__ */ React.createElement(
    "div",
    {
      ...divProps,
      ref,
      key: sceneChild.state.key,
      "data-griditem-key": sceneChild.state.key,
      className: cx(className, props.className),
      style
    },
    innerContent,
    children
  );
});
GridItemWrapper.displayName = "GridItemWrapper";
function validateChildrenSize(children) {
  if (children.some(
    (c) => c.state.height === void 0 || c.state.width === void 0 || c.state.x === void 0 || c.state.y === void 0
  )) {
    throw new Error("All children must have a size specified");
  }
}
function updateAnimationClass(ref, isDraggable, retry) {
  if (ref.current) {
    if (isDraggable) {
      ref.current.classList.add("react-grid-layout--enable-move-animations");
    } else {
      ref.current.classList.remove("react-grid-layout--enable-move-animations");
    }
  } else if (!retry) {
    setTimeout(() => updateAnimationClass(ref, isDraggable, true), 50);
  }
}
const ResizeHandle = React.forwardRef(({ handleAxis, ...divProps }, ref) => {
  const customCssClass = useStyles2(getResizeHandleStyles);
  return /* @__PURE__ */ React.createElement("div", { ref, ...divProps, className: `${customCssClass} scene-resize-handle` }, /* @__PURE__ */ React.createElement("svg", { width: "16px", height: "16px", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React.createElement(
    "path",
    {
      d: "M21 15L15 21M21 8L8 21",
      stroke: "currentColor",
      strokeWidth: "2",
      strokeLinecap: "round",
      strokeLinejoin: "round"
    }
  )));
});
ResizeHandle.displayName = "ResizeHandle";
function getResizeHandleStyles(theme) {
  return css({
    position: "absolute",
    bottom: 0,
    right: 0,
    zIndex: 999,
    padding: theme.spacing(1.5, 0, 0, 1.5),
    color: theme.colors.border.strong,
    cursor: "se-resize",
    "&:hover": {
      color: theme.colors.text.link
    },
    svg: {
      display: "block"
    },
    ".react-resizable-hide &": {
      display: "none"
    }
  });
}

export { SceneGridLayoutRenderer };
//# sourceMappingURL=SceneGridLayoutRenderer.js.map
