import _extends from '@babel/runtime/helpers/extends';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import 'core-js/modules/es.array.find-index.js';
import React__default, { useState, useRef, useCallback } from 'react';
import PropTypes from 'prop-types';
import { settings } from '../../constants/Settings.js';
import { Dropdown } from '@carbon/react';

var _excluded = ["id", "columnCount", "selectedItem", "items", "dropdownId", "disabled", "direction", "onChange", "translateWithId", "testId"];
var iotPrefix = settings.iotPrefix,
  prefix = settings.prefix;
var itemShape = PropTypes.shape({
  id: PropTypes.string.isRequired,
  text: PropTypes.string.isRequired,
  icon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
  footer: PropTypes.node
});
var propTypes = {
  id: PropTypes.string.isRequired,
  dropdownId: PropTypes.string.isRequired,
  columnCount: PropTypes.number,
  selectedItem: itemShape,
  items: PropTypes.arrayOf(itemShape).isRequired,
  // Dropdown specific props
  /**
   * 'aria-label' of the ListBox component.
   */
  ariaLabel: PropTypes.string,
  /**
   * Specify the direction of the dropdown. Can be either top or bottom.
   */
  direction: PropTypes.oneOf(['top', 'bottom']),
  /**
   * Disable the control
   */
  disabled: PropTypes.bool,
  /**
   * Provide helper text that is used alongside the control label for
   * additional help
   */
  helperText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  /**
   * Specify if the currently selected value is invalid.
   */
  invalid: PropTypes.bool,
  /**
   * Message which is displayed if the value is invalid.
   */
  invalidText: PropTypes.string,
  /**
   * Generic `label` that will be used as the textual representation of what
   * this field is for
   */
  label: PropTypes.node.isRequired,
  /**
   * `true` to use the light version.
   */
  light: PropTypes.bool,
  /**
   * `onChange` is a utility for this controlled component to communicate to a
   * consuming component what kind of internal state changes are occurring.
   */
  onChange: PropTypes.func,
  translateWithId: PropTypes.func,
  /**
   * Provide the title text that will be read by a screen reader when
   * visiting this control
   */
  titleText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  /**
   * The dropdown type, `default` or `inline`
   */
  type: PropTypes.oneOf(['default', 'inline']),
  testId: PropTypes.string
};

/* istanbul ignore next, ignore the default onChange */
var defaultPropTypes = {
  columnCount: 4,
  selectedItem: null,
  disabled: false,
  type: 'default',
  light: false,
  titleText: '',
  helperText: '',
  direction: 'bottom',
  ariaLabel: '',
  invalid: false,
  invalidText: '',
  onChange: function onChange() {},
  translateWithId: undefined,
  testId: 'icon-dropdown'
};
var defaultItemSize = 48;
var defaultHelperPadding = 4;
var IconDropdown = function IconDropdown(_ref) {
  var id = _ref.id,
    columnCount = _ref.columnCount,
    controlledSelectedItem = _ref.selectedItem,
    items = _ref.items,
    dropdownId = _ref.dropdownId;
    _ref.disabled;
    var direction = _ref.direction,
    _onChange = _ref.onChange,
    translateWithId = _ref.translateWithId,
    testId = _ref.testId,
    other = _objectWithoutProperties(_ref, _excluded);
  var _useState = useState(false),
    _useState2 = _slicedToArray(_useState, 2),
    isOpen = _useState2[0],
    setIsOpen = _useState2[1];
  var _useState3 = useState(-1),
    _useState4 = _slicedToArray(_useState3, 2),
    highlightedIndex = _useState4[0],
    setHighlightedIndex = _useState4[1];
  var _useState5 = useState(controlledSelectedItem),
    _useState6 = _slicedToArray(_useState5, 2),
    internalSelectedItem = _useState6[0],
    setInternalSelectedItem = _useState6[1];
  var _useState7 = useState(0),
    _useState8 = _slicedToArray(_useState7, 2),
    height = _useState8[0],
    setHeight = _useState8[1];
  var _useState9 = useState(columnCount * defaultItemSize),
    _useState10 = _slicedToArray(_useState9, 2),
    width = _useState10[0],
    setWidth = _useState10[1];
  var _useState11 = useState(0),
    _useState12 = _slicedToArray(_useState11, 2),
    topTranslate = _useState12[0],
    setTopTranslate = _useState12[1];
  var _useState13 = useState(0),
    _useState14 = _slicedToArray(_useState13, 2),
    bottomTranslate = _useState14[0],
    setBottomTranslate = _useState14[1];
  var selectedItem = controlledSelectedItem !== null ? controlledSelectedItem : internalSelectedItem;
  var dropdownRef = useRef(null);
  var highlightedItem = highlightedIndex >= 0 && highlightedIndex < items.length ? items[highlightedIndex] : null;

  // const hasFooter = highlightedItem || selectedItem;

  var handleClick = useCallback(function () {
    var _menuOption$offsetWid;
    // Takes measurements of the dropdown and text that renders beneath this - used to position the footer
    // const dropdown = document.getElementById(id);
    var helperText = dropdownRef.current.getElementsByClassName("".concat(prefix, "--form__helper-text"))[0];
    var validationText = dropdownRef.current.getElementsByClassName("".concat(prefix, "--form-requirement"))[0];
    var menuOption = dropdownRef.current.getElementsByClassName("".concat(prefix, "--list-box__menu-item"))[0];
    var dropdownLabel = dropdownRef.current.getElementsByClassName("".concat(prefix, "--list-box__field"))[0];
    var helperTextHeight = helperText !== undefined ? helperText.clientHeight + defaultHelperPadding : 0;
    var validationTextHeight = validationText !== undefined ? validationText.clientHeight + defaultHelperPadding : 0;
    var labelHeight = dropdownLabel !== undefined ? dropdownLabel.clientHeight : 0;
    setWidth(columnCount * ((_menuOption$offsetWid = menuOption === null || menuOption === void 0 ? void 0 : menuOption.offsetWidth) !== null && _menuOption$offsetWid !== void 0 ? _menuOption$offsetWid : defaultItemSize));
    setHeight(Math.ceil(items.length / columnCount) * defaultItemSize);
    setTopTranslate(helperTextHeight + validationTextHeight + labelHeight + 1); // Add one for the border width
    setBottomTranslate(helperTextHeight + validationTextHeight);
  }, [columnCount, dropdownRef, items.length]);
  var Footer = function Footer() {
    var selectedFooter = highlightedItem !== null ? highlightedItem : selectedItem;
    return /*#__PURE__*/React__default.createElement("div", {
      "data-testid": "".concat(testId, "-footer"),
      className: "".concat(iotPrefix, "--icon-dropdown__footer"),
      style: {
        width: "".concat(width, "px"),
        transform: "translateY(-".concat(direction === 'top' ? topTranslate : bottomTranslate, "px)"),
        paddingTop: direction === 'bottom' ? "".concat(height, "px") : 0,
        paddingBottom: direction === 'top' ? "".concat(height, "px") : 0,
        bottom: direction === 'top' ? 0 : 'initial'
      }
    }, selectedFooter && /*#__PURE__*/React__default.createElement("div", {
      className: "".concat(iotPrefix, "--icon-dropdown__footer-content")
    }, selectedFooter.footer));
  };
  var itemToElement = function itemToElement(item) {
    var index = items.findIndex(function (element) {
      return element.id === item.id;
    });
    return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
      className: "".concat(iotPrefix, "--icon-dropdown__selected-icon-label"),
      onMouseEnter: function onMouseEnter() {
        if (index !== highlightedIndex) {
          setHighlightedIndex(index);
        }
      }
    }, /*#__PURE__*/React__default.createElement(item.icon), /*#__PURE__*/React__default.createElement("div", {
      className: "".concat(iotPrefix, "--icon-dropdown__selected-icon-label__content")
    }, item.text)));
  };
  return /*#__PURE__*/React__default.createElement("div", {
    id: id,
    ref: dropdownRef
  }, isOpen && direction === 'top' && /*#__PURE__*/React__default.createElement(Footer, null), /*#__PURE__*/React__default.createElement(Dropdown, _extends({
    id: dropdownId,
    direction: direction,
    style: {
      width: "".concat(width, "px")
    },
    items: items,
    className: "".concat(iotPrefix, "--icon-dropdown__selection-buttons"),
    selectedItem: selectedItem,
    onChange: function onChange(_ref2) {
      var newSelected = _ref2.selectedItem;
      setInternalSelectedItem(newSelected);
      _onChange(newSelected);
    },
    translateWithId: translateWithId,
    renderSelectedItem: itemToElement,
    downshiftProps: {
      isOpen: isOpen,
      onStateChange: function onStateChange(change) {
        handleClick();
        if (change.isOpen !== undefined) {
          setIsOpen(change.isOpen);
        }
        if (change.highlightedIndex !== undefined) {
          setHighlightedIndex(change.highlightedIndex);
        }
      }
    },
    "data-testid": testId
  }, other, {
    itemToElement: itemToElement,
    itemToString: function itemToString(item) {
      return item.text;
    }
  })), isOpen && direction === 'bottom' && /*#__PURE__*/React__default.createElement(Footer, null));
};
IconDropdown.propTypes = propTypes;
IconDropdown.defaultProps = defaultPropTypes;
IconDropdown.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "IconDropdown",
  "props": {
    "columnCount": {
      "defaultValue": {
        "value": "4",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "number"
      },
      "required": false
    },
    "selectedItem": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "custom",
        "raw": "itemShape"
      },
      "required": false
    },
    "disabled": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "Disable the control",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "type": {
      "defaultValue": {
        "value": "'default'",
        "computed": false
      },
      "description": "The dropdown type, `default` or `inline`",
      "type": {
        "name": "enum",
        "value": [{
          "value": "'default'",
          "computed": false
        }, {
          "value": "'inline'",
          "computed": false
        }]
      },
      "required": false
    },
    "light": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "`true` to use the light version.",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "titleText": {
      "defaultValue": {
        "value": "''",
        "computed": false
      },
      "description": "Provide the title text that will be read by a screen reader when\nvisiting this control",
      "type": {
        "name": "union",
        "value": [{
          "name": "string"
        }, {
          "name": "node"
        }]
      },
      "required": false
    },
    "helperText": {
      "defaultValue": {
        "value": "''",
        "computed": false
      },
      "description": "Provide helper text that is used alongside the control label for\nadditional help",
      "type": {
        "name": "union",
        "value": [{
          "name": "string"
        }, {
          "name": "node"
        }]
      },
      "required": false
    },
    "direction": {
      "defaultValue": {
        "value": "'bottom'",
        "computed": false
      },
      "description": "Specify the direction of the dropdown. Can be either top or bottom.",
      "type": {
        "name": "enum",
        "value": [{
          "value": "'top'",
          "computed": false
        }, {
          "value": "'bottom'",
          "computed": false
        }]
      },
      "required": false
    },
    "ariaLabel": {
      "defaultValue": {
        "value": "''",
        "computed": false
      },
      "description": "'aria-label' of the ListBox component.",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "invalid": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "Specify if the currently selected value is invalid.",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "invalidText": {
      "defaultValue": {
        "value": "''",
        "computed": false
      },
      "description": "Message which is displayed if the value is invalid.",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "onChange": {
      "defaultValue": {
        "value": "() => {}",
        "computed": false
      },
      "description": "`onChange` is a utility for this controlled component to communicate to a\nconsuming component what kind of internal state changes are occurring.",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "translateWithId": {
      "defaultValue": {
        "value": "undefined",
        "computed": true
      },
      "description": "",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "testId": {
      "defaultValue": {
        "value": "'icon-dropdown'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "id": {
      "description": "",
      "type": {
        "name": "string"
      },
      "required": true
    },
    "dropdownId": {
      "description": "",
      "type": {
        "name": "string"
      },
      "required": true
    },
    "items": {
      "description": "",
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "custom",
          "raw": "itemShape"
        }
      },
      "required": true
    },
    "label": {
      "description": "Generic `label` that will be used as the textual representation of what\nthis field is for",
      "type": {
        "name": "node"
      },
      "required": true
    }
  }
};
var IconDropdown$1 = IconDropdown;

export { IconDropdown$1 as default };
