import 'core-js/modules/es.symbol.js';
import 'core-js/modules/es.object.get-own-property-descriptor.js';
import 'core-js/modules/es.object.get-own-property-descriptors.js';
import _extends from '@babel/runtime/helpers/extends';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _pick from '../../node_modules/lodash-es/pick.js';
import 'core-js/modules/es.array.concat.js';
import 'core-js/modules/es.array.filter.js';
import 'core-js/modules/es.array.includes.js';
import 'core-js/modules/es.array.join.js';
import 'core-js/modules/es.array.map.js';
import 'core-js/modules/es.array.splice.js';
import 'core-js/modules/es.object.keys.js';
import 'core-js/modules/es.object.to-string.js';
import 'core-js/modules/es.string.includes.js';
import 'core-js/modules/es.string.starts-with.js';
import 'core-js/modules/es.string.trim.js';
import 'core-js/modules/web.dom-collections.for-each.js';
import React__default, { useState, useRef, useEffect, useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { ComboBox as ComboBox$2, Tag } from '@carbon/react';
import { settings } from '../../constants/Settings.js';
import { filterValidAttributes } from '../../utils/componentUtilityFunctions.js';
import { keyboardKeys } from '../../constants/KeyCodeConstants.js';

var _excluded = ["loading", "wrapperClassName", "closeButtonText", "editOptionText", "hasMultiValue", "onChange", "items", "className", "disabled", "id", "itemToString", "size", "onInputChange", "addToList", "helperText", "shouldFilterItem", "onBlur", "testId", "menuFitContent", "horizontalDirection"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var iotPrefix = settings.iotPrefix;
var propTypes = _objectSpread(_objectSpread({}, ComboBox$2.propTypes), {}, {
  loading: PropTypes.bool,
  // Callback that is called with the value of the input on change
  onChange: PropTypes.func.isRequired,
  // Optional classname to be applied to wrapper
  wrapperClassName: PropTypes.string,
  // String to pass to input field option
  editOptionText: PropTypes.string,
  // String to pass for tags close button aria-label. Will be prepended to value name
  closeButtonText: PropTypes.string,
  // Allow custom onBlur function to be passed to the combobox textinput
  onBlur: PropTypes.func,
  // Bit that will allow mult value and tag feature
  hasMultiValue: PropTypes.bool,
  // On submit/enter, new items should be added to the listbox
  addToList: PropTypes.bool,
  // If true the menu will expand in width to fit the content
  menuFitContent: PropTypes.bool,
  // The horizontal offset direction of the menu. Relevant if menuFitContent is active.
  // Default is 'end' whit means that it expands to the right in normal LTR mode
  horizontalDirection: PropTypes.oneOf(['start', 'end']),
  testId: PropTypes.string
});
var defaultProps = _objectSpread(_objectSpread({}, ComboBox$2.defaultProps), {}, {
  loading: false,
  wrapperClassName: null,
  closeButtonText: 'Close',
  editOptionText: 'Create',
  hasMultiValue: false,
  addToList: false,
  items: [],
  onInputChange: null,
  onBlur: null,
  testId: 'combo',
  menuFitContent: false,
  horizontalDirection: 'end'
});
var ComboBox = /*#__PURE__*/React__default.forwardRef(function (_ref, ref) {
  var loading = _ref.loading,
    wrapperClassName = _ref.wrapperClassName,
    closeButtonText = _ref.closeButtonText,
    editOptionText = _ref.editOptionText,
    hasMultiValue = _ref.hasMultiValue,
    onChange = _ref.onChange,
    items = _ref.items,
    className = _ref.className,
    disabled = _ref.disabled,
    id = _ref.id,
    itemToString = _ref.itemToString,
    size = _ref.size,
    onInputChange = _ref.onInputChange,
    addToList = _ref.addToList,
    helperText = _ref.helperText,
    shouldFilterItem = _ref.shouldFilterItem,
    onBlur = _ref.onBlur,
    testId = _ref.testId,
    menuFitContent = _ref.menuFitContent,
    horizontalDirection = _ref.horizontalDirection,
    rest = _objectWithoutProperties(_ref, _excluded);
  // Ref for the combobox input
  var comboRef = ref || /*#__PURE__*/React__default.createRef();
  // Input value that is added to list
  var _useState = useState(''),
    _useState2 = _slicedToArray(_useState, 2),
    inputValue = _useState2[0],
    setInputValue = _useState2[1];
  // Array that populates list
  var _useState3 = useState(items),
    _useState4 = _slicedToArray(_useState3, 2),
    listItems = _useState4[0],
    setListItems = _useState4[1];
  // Array that populates tags
  var _useState5 = useState([]),
    _useState6 = _slicedToArray(_useState5, 2),
    tagItems = _useState6[0],
    setTagItems = _useState6[1];
  // Array that populates tags
  var prevTagAndListCount = useRef(items.length + tagItems.length);

  // Handle focus after adding new tags or list items
  useEffect(function () {
    var currentTagAndListCount = tagItems.length + listItems.length;

    // only focus input if the tags or list have increased
    if (prevTagAndListCount.current < currentTagAndListCount) {
      comboRef.current.focus();
    }

    // Store the value for the next render
    prevTagAndListCount.current = currentTagAndListCount;
  }, [tagItems, listItems, comboRef]);

  /**
   * List to the blur event and trigger parent onBlur
   * @param {event} e
   */
  var handleOnBlur = function handleOnBlur(e) {
    if (onBlur) {
      onBlur(inputValue, e);
    }
  };
  var handleOnClose = function handleOnClose(e) {
    var _e$currentTarget$pare, _e$currentTarget$pare2;
    // Get close target's text
    var closedValue = (_e$currentTarget$pare = e.currentTarget.parentNode) === null || _e$currentTarget$pare === void 0 || (_e$currentTarget$pare = _e$currentTarget$pare.children[0]) === null || _e$currentTarget$pare === void 0 ? void 0 : _e$currentTarget$pare.textContent;
    // If there is a tag with the same value then remove from tag array
    tagItems.forEach(function (item, idx) {
      if (itemToString(item) === closedValue) {
        tagItems.splice(idx, 1);
        setTagItems(_toConsumableArray(tagItems));
      }
    });
    // Send new value to users onChange callback
    onChange(_toConsumableArray(tagItems));
    // eslint-disable-next-line no-unused-expressions
    (_e$currentTarget$pare2 = e.currentTarget.parentNode) === null || _e$currentTarget$pare2 === void 0 || (_e$currentTarget$pare2 = _e$currentTarget$pare2.parentNode) === null || _e$currentTarget$pare2 === void 0 || (_e$currentTarget$pare2 = _e$currentTarget$pare2.parentNode) === null || _e$currentTarget$pare2 === void 0 || (_e$currentTarget$pare2 = _e$currentTarget$pare2.firstChild) === null || _e$currentTarget$pare2 === void 0 || (_e$currentTarget$pare2 = _e$currentTarget$pare2.children[0]) === null || _e$currentTarget$pare2 === void 0 || (_e$currentTarget$pare2 = _e$currentTarget$pare2.children[1]) === null || _e$currentTarget$pare2 === void 0 || _e$currentTarget$pare2.focus();
  };
  var handleOnChange = function handleOnChange(_ref2) {
    var downShiftSelectedItem = _ref2.selectedItem;
    var newItem = downShiftSelectedItem && Object.keys(downShiftSelectedItem).reduce(function (acc, currentId) {
      var value = downShiftSelectedItem[currentId];
      return _objectSpread(_objectSpread({}, acc), {}, _defineProperty({}, currentId, typeof value === 'string' ? value.trim() : value));
    }, {});
    var currentValue = itemToString(newItem);
    // Check that there is no existing tag
    var hasNoExistingTag = tagItems.filter(function (x) {
      return itemToString(x) === currentValue;
    }).length < 1;
    // Check if value is part of items array
    var isInList = listItems.filter(function (x) {
      return itemToString(x).trim() === currentValue;
    })[0];
    if (hasMultiValue) {
      // If tags array does not contain new value
      if (newItem && hasNoExistingTag) {
        // Add new value to tags array
        setTagItems(function (inputValues) {
          return [].concat(_toConsumableArray(inputValues), [newItem]);
        });
        // pass the combobox value to user's onChange callback
        onChange([].concat(_toConsumableArray(tagItems), [newItem]));
      }
    } else {
      onChange(newItem);
    }
    if ((addToList || hasMultiValue) && typeof (newItem === null || newItem === void 0 ? void 0 : newItem.id) === 'string' && newItem !== null && newItem !== void 0 && newItem.id.startsWith("".concat(iotPrefix, "-input-")) && !isInList) {
      // Add new item to items array
      setListItems(function (currentList) {
        return [newItem].concat(_toConsumableArray(currentList));
      });
    }
    setInputValue(null);
  };

  // If the input text doesn't match something in the list, the CarbonComboBox does not call the onChange handler
  // https://github.com/carbon-design-system/carbon/issues/6613
  var handleOnKeypress = function handleOnKeypress(evt) {
    // Current value of input
    var currentValue = comboRef.current.value.trim();
    if (evt.key === keyboardKeys.ENTER && currentValue) {
      var newItem = {
        id: "".concat(iotPrefix, "-input-").concat(currentValue.split(' ').join('-'), "-").concat(currentValue.length),
        text: currentValue
      };
      handleOnChange({
        selectedItem: newItem
      });
    }
  };
  var handleInputChange = function handleInputChange(e) {
    var matchedItem = listItems.filter(function (x) {
      return itemToString(x) === e;
    })[0];
    if ((onBlur || addToList || hasMultiValue) && e && e !== '' && !matchedItem) {
      setInputValue({
        id: "".concat(iotPrefix, "-input-").concat(e.split(' ').join('-'), "-").concat(e.length),
        text: e
      });
    } else {
      setInputValue(null);
    }
    // Pass on to user callbacks
    if (typeof onInputChange === 'function') {
      onInputChange(e);
    }
  };
  var combinedItems = useMemo(function () {
    return inputValue ? [inputValue].concat(_toConsumableArray(listItems)) : listItems;
  }, [inputValue, listItems]);
  var shouldFilterItemForTags = function shouldFilterItemForTags(_ref3) {
    var _itemToString2;
    var item = _ref3.item,
      _itemToString = _ref3.itemToString,
      _inputValue = _ref3.inputValue;
    return (_itemToString2 = _itemToString(item)) === null || _itemToString2 === void 0 ? void 0 : _itemToString2.includes(_inputValue);
  };
  return (
    /*#__PURE__*/
    // eslint-disable-next-line jsx-a11y/no-static-element-interactions
    React__default.createElement("div", {
      className: classnames("".concat(iotPrefix, "--combobox"), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, wrapperClassName, wrapperClassName), "".concat(iotPrefix, "--combobox-add"), inputValue), "".concat(iotPrefix, "--combobox-size-").concat(size), size), "".concat(iotPrefix, "--combobox-helper-text"), helperText), "".concat(iotPrefix, "--combobox__menu--fit-content"), menuFitContent), "".concat(iotPrefix, "--combobox__menu--flip-horizontal"), horizontalDirection === 'start')),
      onKeyDown: handleOnKeypress,
      onBlur: handleOnBlur,
      "data-testid": "".concat(testId, "-wrapper"),
      "data-edit-option-text": editOptionText
    }, /*#__PURE__*/React__default.createElement(ComboBox$2, _extends({
      "data-testid": "".concat(testId, "-box"),
      id: id,
      key: "tags:".concat(tagItems.length, " listItems:").concat(listItems.length),
      size: size,
      ref: comboRef,
      items: combinedItems,
      itemToString: itemToString,
      onChange: handleOnChange,
      onInputChange: handleInputChange,
      className: classnames(className, "".concat(iotPrefix, "--combobox-input")),
      disabled: disabled || loading !== undefined && loading !== false,
      helperText: helperText,
      shouldFilterItem: hasMultiValue || addToList ? shouldFilterItemForTags : shouldFilterItem
    }, _pick(rest, 'ariaLabel', 'direction', 'downshiftProps', 'initialSelectedItem', 'invalid', 'invalidText', 'itemToElement', 'light', 'onToggleClick', 'placeholder', 'selectedItem', 'titleText', 'translateWithId', 'type', 'warn', 'warnText'), filterValidAttributes(rest))), hasMultiValue ? /*#__PURE__*/React__default.createElement("ul", {
      "data-testid": "".concat(testId, "-tags"),
      className: "".concat(iotPrefix, "--combobox-tags")
    }, tagItems.map(function (item, idx) {
      return /*#__PURE__*/React__default.createElement("li", {
        key: "li-".concat(item === null || item === void 0 ? void 0 : item.id, "-").concat(idx)
      }, /*#__PURE__*/React__default.createElement(Tag, {
        key: "tag-".concat(item === null || item === void 0 ? void 0 : item.id, "-").concat(idx),
        filter: true,
        onClose: function onClose(e) {
          return handleOnClose(e);
        },
        title: closeButtonText
      }, itemToString(item)));
    })) : null)
  );
});
ComboBox.propTypes = propTypes;
ComboBox.defaultProps = defaultProps;
ComboBox.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "ComboBox",
  "props": {
    "loading": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "wrapperClassName": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "closeButtonText": {
      "defaultValue": {
        "value": "'Close'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "editOptionText": {
      "defaultValue": {
        "value": "'Create'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "hasMultiValue": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "addToList": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "items": {
      "defaultValue": {
        "value": "[]",
        "computed": false
      },
      "required": false
    },
    "onInputChange": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "required": false
    },
    "onBlur": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "testId": {
      "defaultValue": {
        "value": "'combo'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "menuFitContent": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "horizontalDirection": {
      "defaultValue": {
        "value": "'end'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "enum",
        "value": [{
          "value": "'start'",
          "computed": false
        }, {
          "value": "'end'",
          "computed": false
        }]
      },
      "required": false
    },
    "onChange": {
      "description": "",
      "type": {
        "name": "func"
      },
      "required": true
    }
  },
  "composes": ["@carbon/react"]
};
var ComboBox$1 = ComboBox;

export { ComboBox$1 as default };
