import { jsx, jsxs } from 'react/jsx-runtime';
import { css } from '@emotion/css';
import memoize from 'micro-memoize';
import RCCascader from 'rc-cascader';
import { PureComponent } from 'react';
import { t } from '@grafana/i18n';
import { withTheme2 } from '../../themes/ThemeContext.mjs';
import { Icon } from '../Icon/Icon.mjs';
import { IconButton } from '../IconButton/IconButton.mjs';
import { Input } from '../Input/Input.mjs';
import { Stack } from '../Layout/Stack/Stack.mjs';
import { Select } from '../Select/Select.mjs';
import { onChangeCascader } from './optionMappings.mjs';
import { getCascaderStyles } from './styles.mjs';

"use strict";
const disableDivFocus = css({
  "&:focus": {
    outline: "none"
  }
});
const DEFAULT_SEPARATOR = " / ";
class UnthemedCascader extends PureComponent {
  constructor(props) {
    super(props);
    this.flattenOptions = (options, optionPath = []) => {
      let selectOptions = [];
      for (const option of options) {
        const cpy = [...optionPath];
        cpy.push(option);
        if (!option.items || option.items.length === 0) {
          selectOptions.push({
            singleLabel: cpy[cpy.length - 1].label,
            label: cpy.map((o) => o.label).join(this.props.separator || DEFAULT_SEPARATOR),
            value: cpy.map((o) => o.value)
          });
        } else {
          selectOptions = [...selectOptions, ...this.flattenOptions(option.items, cpy)];
        }
      }
      return selectOptions;
    };
    this.getSearchableOptions = memoize((options) => this.flattenOptions(options));
    //For rc-cascader
    this.onChange = (value, selectedOptions) => {
      const activeLabel = this.props.hideActiveLevelLabel ? "" : this.props.displayAllSelectedLevels ? selectedOptions.map((option) => option.label).join(this.props.separator || DEFAULT_SEPARATOR) : selectedOptions[selectedOptions.length - 1].label;
      const state = {
        rcValue: { value, label: activeLabel },
        focusCascade: true,
        activeLabel,
        isSearching: false,
        inputValue: activeLabel
      };
      this.setState(state);
      this.props.onSelect(selectedOptions[selectedOptions.length - 1].value);
    };
    //For select
    this.onSelect = (obj) => {
      const valueArray = obj.value || [];
      const activeLabel = this.props.displayAllSelectedLevels ? obj.label : obj.singleLabel || "";
      const state = {
        activeLabel,
        inputValue: activeLabel,
        rcValue: { value: valueArray, label: activeLabel },
        isSearching: false,
        focusCascade: false
      };
      this.setState(state);
      this.props.onSelect(valueArray[valueArray.length - 1]);
    };
    this.onCreateOption = (value) => {
      this.setState({
        activeLabel: value,
        inputValue: value,
        rcValue: [],
        isSearching: false
      });
      this.props.onSelect(value);
    };
    this.onBlur = () => {
      var _a, _b;
      this.setState({
        isSearching: false,
        focusCascade: false
      });
      if (this.state.activeLabel === "") {
        this.setState({
          rcValue: []
        });
      }
      (_b = (_a = this.props).onBlur) == null ? void 0 : _b.call(_a);
    };
    this.onBlurCascade = () => {
      var _a, _b;
      this.setState({
        focusCascade: false
      });
      (_b = (_a = this.props).onBlur) == null ? void 0 : _b.call(_a);
    };
    this.onInputKeyDown = (e) => {
      if (["ArrowDown", "ArrowUp", "Enter", "ArrowLeft", "ArrowRight"].includes(e.key)) {
        return;
      }
      const selectionStart = e.currentTarget.selectionStart;
      const selectionEnd = e.currentTarget.selectionEnd;
      let inputValue = e.currentTarget.value;
      if (selectionStart !== selectionEnd) {
        inputValue = inputValue.substring(0, selectionStart != null ? selectionStart : 0) + inputValue.substring(selectionEnd != null ? selectionEnd : 0);
      }
      this.setState({
        focusCascade: false,
        isSearching: true,
        inputValue
      });
    };
    this.onSelectInputChange = (value) => {
      this.setState({
        inputValue: value
      });
    };
    const searchableOptions = this.getSearchableOptions(props.options);
    const { rcValue, activeLabel } = this.setInitialValue(searchableOptions, props.initialValue);
    this.state = {
      isSearching: false,
      focusCascade: false,
      rcValue,
      activeLabel,
      inputValue: ""
    };
  }
  setInitialValue(searchableOptions, initValue) {
    if (!initValue) {
      return { rcValue: [], activeLabel: "" };
    }
    for (const option of searchableOptions) {
      const optionPath = option.value || [];
      if (optionPath[optionPath.length - 1] === initValue) {
        return {
          rcValue: optionPath,
          activeLabel: this.props.displayAllSelectedLevels ? option.label : option.singleLabel || ""
        };
      }
    }
    if (this.props.allowCustomValue) {
      return { rcValue: [], activeLabel: initValue };
    }
    return { rcValue: [], activeLabel: "" };
  }
  render() {
    const {
      allowCustomValue,
      formatCreateLabel,
      placeholder,
      width,
      changeOnSelect,
      options,
      disabled,
      id,
      isClearable,
      theme
    } = this.props;
    const { focusCascade, isSearching, rcValue, activeLabel, inputValue } = this.state;
    const searchableOptions = this.getSearchableOptions(options);
    const styles = getCascaderStyles(theme);
    return /* @__PURE__ */ jsx("div", { children: isSearching ? /* @__PURE__ */ jsx(
      Select,
      {
        allowCustomValue,
        placeholder,
        autoFocus: !focusCascade,
        onChange: this.onSelect,
        onBlur: this.onBlur,
        options: searchableOptions,
        onCreateOption: this.onCreateOption,
        formatCreateLabel,
        width,
        onInputChange: this.onSelectInputChange,
        disabled,
        inputValue,
        inputId: id
      }
    ) : /* @__PURE__ */ jsx(
      RCCascader,
      {
        onChange: onChangeCascader(this.onChange),
        options,
        changeOnSelect,
        value: rcValue.value,
        fieldNames: { label: "label", value: "value", children: "items" },
        expandIcon: null,
        open: this.props.alwaysOpen,
        disabled,
        dropdownClassName: styles.dropdown,
        children: /* @__PURE__ */ jsx("div", { className: disableDivFocus, children: /* @__PURE__ */ jsx(
          Input,
          {
            autoFocus: this.props.autoFocus,
            width,
            placeholder,
            onBlur: this.onBlurCascade,
            value: activeLabel,
            onFocus: (e) => {
              e.currentTarget.select();
            },
            onKeyDown: this.onInputKeyDown,
            onChange: () => {
            },
            suffix: /* @__PURE__ */ jsxs(Stack, { gap: 0.5, children: [
              isClearable && activeLabel !== "" && /* @__PURE__ */ jsx(
                IconButton,
                {
                  name: "times",
                  "aria-label": t("grafana-ui.cascader.clear-button", "Clear selection"),
                  onClick: (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    this.setState({ rcValue: [], activeLabel: "", inputValue: "" });
                    this.props.onSelect("");
                  }
                }
              ),
              /* @__PURE__ */ jsx(Icon, { name: focusCascade ? "angle-up" : "angle-down" })
            ] }),
            disabled,
            id
          }
        ) })
      }
    ) });
  }
}
UnthemedCascader.defaultProps = { changeOnSelect: true };
const Cascader = withTheme2(UnthemedCascader);

export { Cascader };
//# sourceMappingURL=Cascader.mjs.map
