import React, { useRef, useState, useMemo } from 'react';
import classNames from 'classnames';
import { faXmark } from '@fortawesome/free-solid-svg-icons/faXmark';
import { FontAwesomeIcon } from '../../font-awesome-icon';
import MultiSelectLabel from './multi-select-label';
import { useTranslation } from '../../hooks/use-translation';
import Typeahead from '../typeahead';
import { ValidityMessages, MESSAGE_DISPLAY_LOCATION, HELPER_TEXT_POSITION, FormFieldLabel } from '../../form-field';
import { Button, ACCENT_TYPES, BUTTON_SIZES } from '../../button';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function filterSelectedOptions(options, selectedOptions = [], optionLabel = '') {
  // items can contain strings or objects like { [optionLabel]: 'value' }
  const selectedOptionLabels = selectedOptions.map(o => {
    return String(o?.[optionLabel] ?? o);
  });
  if (options && selectedOptionLabels.length && optionLabel) {
    if (Array.isArray(options)) {
      return options.filter(o => !selectedOptionLabels.includes(String(o[optionLabel])));
    }
    if (Object.keys(options).length) {
      return Object.keys(options).reduce((acc, key) => {
        if (Array.isArray(options[key])) {
          return {
            [key]: filterSelectedOptions(options[key], selectedOptionLabels, optionLabel),
            ...acc
          };
        }
        return acc;
      }, {});
    }
  }
  return options;
}
/**
 * @midnight-gray-supported
 * @alpine-light-supported
 */
function MultiSelectTypeahead({
  items = [],
  OptionList,
  optionComponent,
  LabelComponent = MultiSelectLabel,
  onDelete = () => {},
  onSearch = () => {},
  onSelect = () => {},
  options = [],
  optionId,
  isDisabled = false,
  autoFocus = false,
  optionLabel = 'label',
  searchFields = [],
  asyncValidation,
  placeholder = '',
  maxItems,
  id = '',
  label = '',
  helperText = '',
  labelTestId,
  labelIcon,
  labelIconTestId = '',
  labelIconTooltipText = '',
  testId,
  helperTextPosition = HELPER_TEXT_POSITION.TOP,
  containerTestId = 'multi-select-container',
  hasErrored = false,
  showAllOnFocus = false,
  keepInvalidText = false,
  dropdownContentClass = '',
  multiselectContainerClass = '',
  className = '',
  onBlur = () => {},
  onKeyDown = () => {},
  onClearAll = () => {},
  clearAllTooltipText,
  clearAllAriaLabel,
  removeLabelText,
  isClearAllEnabled = false,
  inputRef,
  validity,
  noItemsText,
  invalidItems = [],
  isRequired = false,
  isOptional = false,
  optionalLabelText,
  shouldShowSelectedOptions = false
}) {
  const {
    t
  } = useTranslation();
  const clearAllTooltipTextWithDefault = clearAllTooltipText ?? t('Clear all');
  const [focused, toggleFocus] = useState(autoFocus);
  const availableOptions = useMemo(() => shouldShowSelectedOptions ? options : filterSelectedOptions(options, items, optionLabel), [options, items, optionLabel]);
  const handleFocus = bool => toggleFocus(bool);
  const handleBlur = searchValue => {
    // Only handle blur if necessary for options that should not close dropdown.
    const shouldNotBlur = options.some(opt => opt.shouldNotCloseDropdown);
    if (shouldNotBlur) {
      return;
    }
    toggleFocus(false);
    onBlur(searchValue);
  };
  const handleDelete = (currentValue, index) => {
    for (const opt of options) {
      if (opt.title === currentValue && opt.isDisabled === true) {
        return;
      }
    }
    onDelete(currentValue, index);
  };
  const containerRef = useRef(null);
  const hasReachedMaxItems = Boolean(maxItems && items.length >= maxItems);
  const validityDisplayLocation = validity?.displayLocation ?? MESSAGE_DISPLAY_LOCATION.INLINE;
  const showValidationResult = Boolean(validity?.value);
  const showClearAllButton = isClearAllEnabled;
  const isDisabledItem = value => {
    for (const obj of options) {
      if (obj.title === value && obj.isDisabled) {
        return true;
      }
    }
    return false;
  };
  return /*#__PURE__*/_jsxs("div", {
    className: classNames('multi-select-typeahead', className),
    children: [label && id && /*#__PURE__*/_jsx(FormFieldLabel, {
      label: label,
      isDisabled: isDisabled,
      id: id,
      labelTestId: labelTestId,
      labelIcon: labelIcon,
      labelIconTestId: labelIconTestId,
      labelIconTooltipText: labelIconTooltipText,
      isRequired: isRequired,
      isOptional: isOptional,
      optionalLabelText: optionalLabelText ?? t('Optional')
    }), helperText && helperTextPosition === HELPER_TEXT_POSITION.TOP && /*#__PURE__*/_jsx("div", {
      className: classNames('helper-text', {
        disabled: isDisabled
      }),
      "test-id": "multi-select-typeahead-helper-text",
      children: helperText
    }), /*#__PURE__*/_jsxs("div", {
      className: classNames('multi-select-container', multiselectContainerClass, {
        focused: !isDisabled && focused && !hasReachedMaxItems,
        disabled: isDisabled || hasReachedMaxItems,
        error: hasErrored
      }),
      onClick: event => {
        // don't focus if clicked on remove button
        const tagName = event.target.tagName;
        if (['svg', 'path'].includes(tagName)) {
          return;
        }
        handleFocus(true);
      },
      ref: containerRef,
      "test-id": containerTestId,
      children: [/*#__PURE__*/_jsxs("div", {
        className: "multi-select-values",
        children: [items.map((value, index) => /*#__PURE__*/_jsx(LabelComponent, {
          value: value,
          onDelete: currentValue => handleDelete(currentValue, index),
          disabled: isDisabled,
          isReadOnlyItem: isDisabledItem(value),
          isInvalid: invalidItems.includes(value),
          removeLabelText: removeLabelText ?? t('Remove')
        }, index)), /*#__PURE__*/_jsx(Typeahead, {
          containerRef: containerRef,
          inputRef: inputRef,
          fieldClass: "multi-select-input",
          placeholder: !!items.length ? '' : placeholder,
          OptionList: OptionList,
          optionComponent: optionComponent,
          onSearch: onSearch,
          onSelect: onSelect,
          onDelete: handleDelete,
          items: items,
          isDisabled: isDisabled || hasReachedMaxItems,
          searchFields: searchFields,
          helperTextPosition: helperTextPosition,
          optionId: optionId,
          optionLabel: optionLabel,
          options: availableOptions,
          isMultiSelect: true,
          focused: focused,
          handleFocus: handleFocus,
          id: id,
          testId: testId,
          showAllOnFocus: showAllOnFocus,
          keepInvalidText: keepInvalidText,
          dropdownContentClass: dropdownContentClass,
          asyncValidation: asyncValidation,
          autoComplete: "off",
          onBlur: handleBlur,
          onKeyDown: onKeyDown,
          noItemsText: noItemsText
        })]
      }), showClearAllButton && !!items.length && !isDisabled && /*#__PURE__*/_jsx(Button, {
        className: "clear-all-button",
        accentType: ACCENT_TYPES.ROUND_ICON,
        size: BUTTON_SIZES.XS,
        onClick: onClearAll,
        tooltipText: clearAllTooltipTextWithDefault,
        "aria-label": clearAllAriaLabel || clearAllTooltipTextWithDefault,
        testId: "clear-all-button",
        children: /*#__PURE__*/_jsx(FontAwesomeIcon, {
          icon: faXmark
        })
      })]
    }), helperText && helperTextPosition === HELPER_TEXT_POSITION.BOTTOM && /*#__PURE__*/_jsx("div", {
      className: classNames('helper-text helper-text-bottom', {
        disabled: isDisabled
      }),
      children: helperText
    }), validity && showValidationResult && validityDisplayLocation === MESSAGE_DISPLAY_LOCATION.INLINE && /*#__PURE__*/_jsx(ValidityMessages, {
      validationTestId: 'multi-select-validation',
      validity: validity,
      fieldId: id
    })]
  });
}
export default MultiSelectTypeahead;