import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/esm/taggedTemplateLiteralLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";

function _templateObject() {
  var data = _taggedTemplateLiteralLoose(["none"]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

import React, { useRef, useState, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import pick from 'lodash/pick';
import isUndefined from 'lodash/isUndefined';
import isNil from 'lodash/isNil';
import isFunction from 'lodash/isFunction';
import omit from 'lodash/omit';
import { createChainedFunction, getDataGroupBy, useCustom, useClassNames, useControlled, mergeRefs, shallowEqual } from '../utils';
import { DropdownMenu, DropdownMenuItem, PickerToggle, PickerToggleTrigger, PickerOverlay, SearchBar, useFocusItemValue, usePickerClassName, useSearch, usePublicMethods, useToggleKeyDownEvent, pickTriggerPropKeys, omitTriggerPropKeys, listPickerPropTypes } from '../Picker';
var defaultProps = {
  as: 'div',
  appearance: 'default',
  classPrefix: 'picker',
  searchable: true,
  cleanable: true,
  data: [],
  disabledItemValues: [],
  valueKey: 'value',
  labelKey: 'label',
  placement: 'bottomStart',
  menuAutoWidth: true,
  menuMaxHeight: 320
};
var SelectPicker = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var Component = props.as,
      data = props.data,
      valueKey = props.valueKey,
      labelKey = props.labelKey,
      valueProp = props.value,
      classPrefix = props.classPrefix,
      placeholder = props.placeholder,
      defaultValue = props.defaultValue,
      disabled = props.disabled,
      cleanable = props.cleanable,
      placement = props.placement,
      menuClassName = props.menuClassName,
      menuAutoWidth = props.menuAutoWidth,
      menuMaxHeight = props.menuMaxHeight,
      menuStyle = props.menuStyle,
      groupBy = props.groupBy,
      overrideLocale = props.locale,
      toggleAs = props.toggleAs,
      style = props.style,
      searchable = props.searchable,
      disabledItemValues = props.disabledItemValues,
      virtualized = props.virtualized,
      listProps = props.listProps,
      id = props.id,
      onGroupTitleClick = props.onGroupTitleClick,
      searchBy = props.searchBy,
      onEntered = props.onEntered,
      onExited = props.onExited,
      onClean = props.onClean,
      onChange = props.onChange,
      onSelect = props.onSelect,
      onSearch = props.onSearch,
      onClose = props.onClose,
      onOpen = props.onOpen,
      sort = props.sort,
      renderValue = props.renderValue,
      renderMenu = props.renderMenu,
      renderMenuGroup = props.renderMenuGroup,
      renderMenuItem = props.renderMenuItem,
      renderExtraFooter = props.renderExtraFooter,
      rest = _objectWithoutPropertiesLoose(props, ["as", "data", "valueKey", "labelKey", "value", "classPrefix", "placeholder", "defaultValue", "disabled", "cleanable", "placement", "menuClassName", "menuAutoWidth", "menuMaxHeight", "menuStyle", "groupBy", "locale", "toggleAs", "style", "searchable", "disabledItemValues", "virtualized", "listProps", "id", "onGroupTitleClick", "searchBy", "onEntered", "onExited", "onClean", "onChange", "onSelect", "onSearch", "onClose", "onOpen", "sort", "renderValue", "renderMenu", "renderMenuGroup", "renderMenuItem", "renderExtraFooter"]);

  var triggerRef = useRef();
  var targetRef = useRef();
  var overlayRef = useRef();

  var _useCustom = useCustom('Picker', overrideLocale),
      locale = _useCustom.locale;

  var _useControlled = useControlled(valueProp, defaultValue),
      value = _useControlled[0],
      setValue = _useControlled[1]; // Used to hover the focus item  when trigger `onKeydown`


  var _useFocusItemValue = useFocusItemValue(value, {
    data: data,
    valueKey: valueKey,
    target: function target() {
      return overlayRef.current;
    }
  }),
      focusItemValue = _useFocusItemValue.focusItemValue,
      setFocusItemValue = _useFocusItemValue.setFocusItemValue,
      onFocusItem = _useFocusItemValue.onKeyDown; // Use search keywords to filter options.


  var _useSearch = useSearch({
    labelKey: labelKey,
    data: data,
    searchBy: searchBy,
    callback: function callback(searchKeyword, filteredData, event) {
      var _filteredData$;

      // The first option after filtering is the focus.
      setFocusItemValue(filteredData === null || filteredData === void 0 ? void 0 : (_filteredData$ = filteredData[0]) === null || _filteredData$ === void 0 ? void 0 : _filteredData$[valueKey]);
      onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchKeyword, event);
    }
  }),
      searchKeyword = _useSearch.searchKeyword,
      filteredData = _useSearch.filteredData,
      updateFilteredData = _useSearch.updateFilteredData,
      setSearchKeyword = _useSearch.setSearchKeyword,
      handleSearch = _useSearch.handleSearch;

  useEffect(function () {
    updateFilteredData(data);
  }, [data, updateFilteredData]); // Use component active state to support keyboard events.

  var _useState = useState(false),
      active = _useState[0],
      setActive = _useState[1];

  var handleClose = useCallback(function () {
    var _triggerRef$current, _triggerRef$current$c;

    (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : (_triggerRef$current$c = _triggerRef$current.close) === null || _triggerRef$current$c === void 0 ? void 0 : _triggerRef$current$c.call(_triggerRef$current);
  }, []);
  var handleSelect = useCallback(function (value, item, event) {
    var _targetRef$current;

    onSelect === null || onSelect === void 0 ? void 0 : onSelect(value, item, event);
    (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.focus();
  }, [onSelect]);
  var handleChangeValue = useCallback(function (value, event) {
    onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
  }, [onChange]);
  var handleMenuPressEnter = useCallback(function (event) {
    if (!focusItemValue) {
      return;
    } // Find active `MenuItem` by `value`


    var focusItem = data.find(function (item) {
      return shallowEqual(item[valueKey], focusItemValue);
    });
    setValue(focusItemValue);
    handleSelect(focusItemValue, focusItem, event);
    handleChangeValue(focusItemValue, event);
    handleClose();
  }, [data, focusItemValue, handleChangeValue, handleClose, handleSelect, setValue, valueKey]);
  var handleItemSelect = useCallback(function (value, item, event) {
    setValue(value);
    setFocusItemValue(value);
    handleSelect(value, item, event);
    handleChangeValue(value, event);
    handleClose();
  }, [setValue, setFocusItemValue, handleSelect, handleChangeValue, handleClose]);
  var handleClean = useCallback(function (event) {
    if (disabled || !cleanable) {
      return;
    }

    setValue(null);
    setFocusItemValue(value);
    handleChangeValue(null, event);
  }, [value, disabled, cleanable, setValue, handleChangeValue, setFocusItemValue]);
  var onPickerKeyDown = useToggleKeyDownEvent(_extends({
    toggle: !focusItemValue || !active,
    triggerRef: triggerRef,
    targetRef: targetRef,
    overlayRef: overlayRef,
    active: active,
    onExit: handleClean,
    onMenuKeyDown: onFocusItem,
    onMenuPressEnter: handleMenuPressEnter,
    onClose: function onClose() {
      setFocusItemValue(null);
    }
  }, rest));
  var handleExited = useCallback(function () {
    setSearchKeyword('');
    setActive(false);
    onClose === null || onClose === void 0 ? void 0 : onClose();
  }, [onClose, setSearchKeyword]);
  var handleEntered = useCallback(function () {
    setActive(true);
    setFocusItemValue(value);
    onOpen === null || onOpen === void 0 ? void 0 : onOpen();
  }, [onOpen, setFocusItemValue, value]);
  usePublicMethods(ref, {
    triggerRef: triggerRef,
    overlayRef: overlayRef,
    targetRef: targetRef
  }); // Find active `MenuItem` by `value`

  var activeItem = data.find(function (item) {
    return shallowEqual(item[valueKey], value);
  });
  /**
   * 1.Have a value and the value is valid.
   * 2.Regardless of whether the value is valid, as long as renderValue is set, it is judged to have a value.
   */

  var hasValue = !!activeItem || !isNil(value) && isFunction(renderValue);

  var _useClassNames = useClassNames(classPrefix),
      prefix = _useClassNames.prefix,
      merge = _useClassNames.merge;

  var selectedElement = placeholder;

  if (activeItem === null || activeItem === void 0 ? void 0 : activeItem[labelKey]) {
    selectedElement = activeItem[labelKey];
  }

  if (!isNil(value) && isFunction(renderValue)) {
    selectedElement = renderValue(value, activeItem, selectedElement); // If renderValue returns null or undefined, hasValue is false.

    if (isNil(selectedElement)) {
      hasValue = false;
    }
  }

  var renderDropdownMenu = function renderDropdownMenu(positionProps, speakerRef) {
    var left = positionProps.left,
        top = positionProps.top,
        className = positionProps.className;
    var classes = merge(className, menuClassName, prefix('select-menu'));

    var styles = _extends({}, menuStyle, {
      left: left,
      top: top
    });

    var items = filteredData; // Create a tree structure data when set `groupBy`

    if (groupBy) {
      items = getDataGroupBy(items, groupBy, sort);
    } else if (typeof sort === 'function') {
      items = items.sort(sort(false));
    }

    var menu = items.length ? /*#__PURE__*/React.createElement(DropdownMenu, {
      id: id ? id + "-listbox" : undefined,
      listProps: listProps,
      disabledItemValues: disabledItemValues,
      valueKey: valueKey,
      labelKey: labelKey,
      renderMenuGroup: renderMenuGroup,
      renderMenuItem: renderMenuItem,
      maxHeight: menuMaxHeight,
      classPrefix: 'picker-select-menu',
      dropdownMenuItemClassPrefix: 'picker-select-menu-item',
      dropdownMenuItemAs: DropdownMenuItem,
      activeItemValues: [value],
      focusItemValue: focusItemValue,
      data: items,
      group: !isUndefined(groupBy),
      onSelect: handleItemSelect,
      onGroupTitleClick: onGroupTitleClick,
      virtualized: virtualized
    }) : /*#__PURE__*/React.createElement("div", {
      className: prefix(_templateObject())
    }, locale === null || locale === void 0 ? void 0 : locale.noResultsText);
    return /*#__PURE__*/React.createElement(PickerOverlay, {
      ref: mergeRefs(overlayRef, speakerRef),
      autoWidth: menuAutoWidth,
      className: classes,
      style: styles,
      onKeyDown: onPickerKeyDown,
      target: triggerRef
    }, searchable && /*#__PURE__*/React.createElement(SearchBar, {
      placeholder: locale === null || locale === void 0 ? void 0 : locale.searchPlaceholder,
      onChange: handleSearch,
      value: searchKeyword
    }), renderMenu ? renderMenu(menu) : menu, renderExtraFooter === null || renderExtraFooter === void 0 ? void 0 : renderExtraFooter());
  };

  var _usePickerClassName = usePickerClassName(_extends({}, props, {
    hasValue: hasValue,
    name: 'select'
  })),
      classes = _usePickerClassName[0],
      usedClassNamePropKeys = _usePickerClassName[1];

  return /*#__PURE__*/React.createElement(PickerToggleTrigger, {
    pickerProps: pick(props, pickTriggerPropKeys),
    ref: triggerRef,
    placement: placement,
    onEntered: createChainedFunction(handleEntered, onEntered),
    onExited: createChainedFunction(handleExited, onExited),
    speaker: renderDropdownMenu
  }, /*#__PURE__*/React.createElement(Component, {
    className: classes,
    style: style
  }, /*#__PURE__*/React.createElement(PickerToggle, _extends({}, omit(rest, [].concat(omitTriggerPropKeys, usedClassNamePropKeys)), {
    id: id,
    ref: targetRef,
    onClean: createChainedFunction(handleClean, onClean),
    onKeyDown: onPickerKeyDown,
    as: toggleAs,
    disabled: disabled,
    cleanable: cleanable && !disabled,
    hasValue: hasValue,
    inputValue: value,
    active: active,
    placement: placement
  }), selectedElement || (locale === null || locale === void 0 ? void 0 : locale.placeholder))));
});
SelectPicker.displayName = 'SelectPicker';
SelectPicker.defaultProps = defaultProps;
SelectPicker.propTypes = _extends({}, listPickerPropTypes, {
  locale: PropTypes.any,
  appearance: PropTypes.oneOf(['default', 'subtle']),
  menuAutoWidth: PropTypes.bool,
  menuMaxHeight: PropTypes.number,
  renderMenu: PropTypes.func,
  renderMenuItem: PropTypes.func,
  renderMenuGroup: PropTypes.func,
  onSelect: PropTypes.func,
  onGroupTitleClick: PropTypes.func,
  onSearch: PropTypes.func,

  /**
   * group by key in `data`
   */
  groupBy: PropTypes.any,
  sort: PropTypes.func,
  searchable: PropTypes.bool,
  virtualized: PropTypes.bool,
  searchBy: PropTypes.func
});
export default SelectPicker;