import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { max } from 'lodash';
import * as React from 'react';
import { useRef, useMemo, useLayoutEffect } from 'react';
import { FixedSizeList } from 'react-window';
import { toIconName } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../themes/ThemeContext.js';
import { Trans } from '../../utils/i18n.js';
import { clearButtonStyles } from '../Button/Button.js';
import '../Button/ButtonGroup.js';
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar.js';
import { Icon } from '../Icon/Icon.js';
import { getSelectStyles } from './getSelectStyles.js';
import { ToggleAllState } from './types.js';

const SelectMenu = ({
  children,
  maxHeight,
  innerRef,
  innerProps,
  selectProps
}) => {
  var _a;
  const theme = useTheme2();
  const styles = getSelectStyles(theme);
  const { toggleAllOptions, components } = selectProps;
  const optionsElement = (_a = components == null ? void 0 : components.Option) != null ? _a : SelectMenuOptions;
  return /* @__PURE__ */ jsx("div", { ...innerProps, className: styles.menu, style: { maxHeight }, "aria-label": "Select options menu", children: /* @__PURE__ */ jsxs(CustomScrollbar, { scrollRefCallback: innerRef, autoHide: false, autoHeightMax: "inherit", hideHorizontalTrack: true, children: [
    toggleAllOptions && /* @__PURE__ */ jsx(
      ToggleAllOption,
      {
        state: toggleAllOptions.state,
        optionComponent: optionsElement,
        selectedCount: toggleAllOptions.selectedCount,
        onClick: toggleAllOptions.selectAllClicked
      }
    ),
    children
  ] }) });
};
SelectMenu.displayName = "SelectMenu";
const VIRTUAL_LIST_ITEM_HEIGHT = 37;
const VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER = 8;
const VIRTUAL_LIST_PADDING = 8;
const VIRTUAL_LIST_WIDTH_EXTRA = 58;
const VirtualizedSelectMenu = ({
  children,
  maxHeight,
  innerRef: scrollRef,
  options,
  selectProps,
  focusedOption
}) => {
  var _a, _b;
  const theme = useTheme2();
  const styles = getSelectStyles(theme);
  const listRef = useRef(null);
  const { toggleAllOptions, components } = selectProps;
  const optionComponent = (_a = components == null ? void 0 : components.Option) != null ? _a : SelectMenuOptions;
  const flattenedOptions = useMemo(
    () => options.flatMap((option) => option.options ? [option, ...option.options] : [option]),
    [options]
  );
  const focusedIndex = flattenedOptions.findIndex(
    (option) => option.value === (focusedOption == null ? void 0 : focusedOption.value)
  );
  useLayoutEffect(() => {
    var _a2;
    (_a2 = listRef.current) == null ? void 0 : _a2.scrollToItem(focusedIndex);
  }, [focusedIndex]);
  if (!Array.isArray(children)) {
    return null;
  }
  const flattenedChildren = children.flatMap((child, index) => {
    if (hasArrayChildren(child)) {
      const childWithoutChildren = React.cloneElement(child, {
        children: null
      });
      return [
        childWithoutChildren,
        ...child.props.children.slice(0, -1),
        // add a bottom divider to the last item in the category
        React.cloneElement(child.props.children.at(-1), {
          innerProps: {
            ...child.props.children.at(-1).props.innerProps,
            style: {
              borderBottom: `1px solid ${theme.colors.border.weak}`,
              height: VIRTUAL_LIST_ITEM_HEIGHT
            }
          }
        })
      ];
    }
    return [child];
  });
  if (toggleAllOptions) {
    flattenedChildren.unshift(
      /* @__PURE__ */ jsx(
        ToggleAllOption,
        {
          optionComponent,
          state: toggleAllOptions.state,
          selectedCount: toggleAllOptions.selectedCount,
          onClick: toggleAllOptions.selectAllClicked
        }
      )
    );
  }
  let longestOption = (_b = max(flattenedOptions.map((option) => {
    var _a2;
    return (_a2 = option.label) == null ? void 0 : _a2.length;
  }))) != null ? _b : 0;
  if (toggleAllOptions && longestOption < 12) {
    longestOption = 12;
  }
  const widthEstimate = longestOption * VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER + VIRTUAL_LIST_PADDING * 2 + VIRTUAL_LIST_WIDTH_EXTRA;
  const heightEstimate = Math.min(flattenedChildren.length * VIRTUAL_LIST_ITEM_HEIGHT, maxHeight);
  return /* @__PURE__ */ jsx(
    FixedSizeList,
    {
      outerRef: scrollRef,
      ref: listRef,
      className: styles.menu,
      height: heightEstimate,
      width: widthEstimate,
      "aria-label": "Select options menu",
      itemCount: flattenedChildren.length,
      itemSize: VIRTUAL_LIST_ITEM_HEIGHT,
      children: ({ index, style }) => /* @__PURE__ */ jsx("div", { style: { ...style, overflow: "hidden" }, children: flattenedChildren[index] })
    }
  );
};
const hasArrayChildren = (child) => {
  return React.isValidElement(child) && Array.isArray(child.props.children);
};
VirtualizedSelectMenu.displayName = "VirtualizedSelectMenu";
const ToggleAllOption = ({
  state,
  onClick,
  selectedCount,
  optionComponent
}) => {
  const theme = useTheme2();
  const styles = getSelectStyles(theme);
  return /* @__PURE__ */ jsx(
    "button",
    {
      "data-testid": selectors.components.Select.toggleAllOptions,
      className: css(clearButtonStyles(theme), styles.toggleAllButton, {
        height: VIRTUAL_LIST_ITEM_HEIGHT
      }),
      onClick,
      children: optionComponent({
        isDisabled: false,
        isSelected: state === ToggleAllState.allSelected,
        isFocused: false,
        data: {},
        indeterminate: state === ToggleAllState.indeterminate,
        innerRef: () => {
        },
        innerProps: {},
        children: /* @__PURE__ */ jsxs(Fragment, { children: [
          /* @__PURE__ */ jsx(Trans, { i18nKey: "select.select-menu.selected-count", children: "Selected " }),
          `(${selectedCount != null ? selectedCount : 0})`
        ] })
      })
    }
  );
};
const SelectMenuOptions = ({
  children,
  data,
  innerProps,
  innerRef,
  isFocused,
  isSelected,
  renderOptionLabel
}) => {
  const theme = useTheme2();
  const styles = getSelectStyles(theme);
  const icon = data.icon ? toIconName(data.icon) : void 0;
  const { onMouseMove, onMouseOver, ...rest } = innerProps;
  return /* @__PURE__ */ jsxs(
    "div",
    {
      ref: innerRef,
      className: cx(
        styles.option,
        isFocused && styles.optionFocused,
        isSelected && styles.optionSelected,
        data.isDisabled && styles.optionDisabled
      ),
      ...rest,
      "data-testid": selectors.components.Select.option,
      title: data.title,
      children: [
        icon && /* @__PURE__ */ jsx(Icon, { name: icon, className: styles.optionIcon }),
        data.imgUrl && /* @__PURE__ */ jsx("img", { className: styles.optionImage, src: data.imgUrl, alt: data.label || String(data.value) }),
        /* @__PURE__ */ jsxs("div", { className: styles.optionBody, children: [
          /* @__PURE__ */ jsx("span", { children: renderOptionLabel ? renderOptionLabel(data) : children }),
          data.description && /* @__PURE__ */ jsx("div", { className: styles.optionDescription, children: data.description }),
          data.component && /* @__PURE__ */ jsx(data.component, {})
        ] })
      ]
    }
  );
};
SelectMenuOptions.displayName = "SelectMenuOptions";

export { SelectMenu, SelectMenuOptions, VirtualizedSelectMenu };
//# sourceMappingURL=SelectMenu.js.map
