"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.CheckboxMultiselectTypeahead = CheckboxMultiselectTypeahead;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _multiSelectTypeahead = _interopRequireDefault(require("./multi-select-typeahead"));
var _useVisibleOptions = require("../use-visible-options");
var _useOptionKeyboardNavigation = require("../../hooks/use-option-keyboard-navigation");
var _useNonNativeButtonAttrs = require("../../hooks/use-non-native-button-attrs");
var _checkbox = require("../../checkbox");
var _truncateWithTooltip = require("../../truncate-with-tooltip");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const SELECT_ALL_KEY = 'SELECT_ALL_KEY';
function CheckboxListItem({
  option,
  optionId,
  optionLabel,
  handleSelect,
  activeOption,
  makeActive,
  onInteraction,
  currentRef,
  optionComponent
}) {
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
    "test-id": `typeahead-dropdown-item-${option[optionId]}`,
    ref: currentRef,
    className: (0, _classnames.default)('typeahead-dropdown-item', {
      active: activeOption && activeOption === option[optionId],
      'sticky-typeahead-dropdown-item': option[optionId] === SELECT_ALL_KEY
    }),
    onMouseEnter: () => makeActive(option[optionId]),
    ...(0, _useNonNativeButtonAttrs.getNonNativeButtonAttrs)({
      isDisabled: option.isDisabled,
      onClick: e => onInteraction(e, option),
      onKeyDown: e => onInteraction(e, option)
    }),
    children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
      className: "checkbox-item-container",
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_checkbox.Checkbox, {
        id: option[optionId],
        testId: `checkbox-${option[optionId]}`,
        className: "margin-right-2",
        onChange: e => {
          e.stopPropagation();
          handleSelect(option);
        },
        isChecked: option.isChecked,
        isDisabled: option.isDisabled,
        indeterminate: option.indeterminate,
        ariaLabel: option[optionLabel]
      }), optionComponent ? (
      /*#__PURE__*/
      // This is wrong way of doing stuff, but I'm, keeping existing typeahead approach for now
      (0, _react.cloneElement)(optionComponent, {
        option,
        optionId,
        optionLabel
      })) : /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
        className: "columns-container",
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
          className: "label-column-container",
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
            className: "label-column",
            children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
              children: option[optionLabel]
            })
          })
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
          className: "additional-columns-container",
          children: option?.additionalColumnsKeys?.map(accessorKey => {
            return /*#__PURE__*/(0, _jsxRuntime.jsx)(_truncateWithTooltip.TruncateWithTooltip, {
              className: "checkbox-item-additional-column",
              children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
                "test-id": `checkbox-item-additional-column-${accessorKey}`,
                children: option[accessorKey]
              }, accessorKey)
            }, accessorKey);
          })
        })]
      })]
    })
  }, String(option[optionId]));
}
function CheckboxOptionList({
  options,
  optionId,
  optionLabel,
  closeDropdown,
  handleSelect,
  searchValue,
  searchFields,
  width,
  inputRef,
  optionComponent,
  listId
}) {
  const {
    visibleOptions
  } = (0, _useVisibleOptions.useVisibleOptions)({
    searchValue,
    options,
    searchFields,
    isShowAll: false
  });
  const scrollableContainerRef = (0, _react.useRef)(null);
  const optionsRefs = visibleOptions.reduce((map, option) => {
    map[option[optionId]] = /*#__PURE__*/_react.default.createRef();
    return map;
  }, {});
  const [activeOption, makeActive] = (0, _useOptionKeyboardNavigation.useOptionKeyboardNavigation)(visibleOptions, optionId, handleSelect, closeDropdown, optionsRefs, scrollableContainerRef, 0, 'isDisabled', inputRef);
  const onInteraction = (e, option) => {
    e.preventDefault();
    handleSelect(option);
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
    className: "typeahead-dropdown-list checkbox-multiselect-container"
    /* eslint-disable-next-line react/forbid-dom-props */,
    style: {
      width
    },
    "test-id": "typeahead-dropdown-list",
    id: listId,
    ref: el => {
      // The element itself is the scrollable container (overflow-y: auto on
      // .checkbox-multiselect-container); keyboard navigation needs the ref
      // here so active options can be scrolled into view.
      scrollableContainerRef.current = el;
    },
    children: visibleOptions.map(option => /*#__PURE__*/(0, _jsxRuntime.jsx)(CheckboxListItem, {
      option: option,
      optionId: optionId,
      optionLabel: optionLabel,
      handleSelect: handleSelect,
      onInteraction: onInteraction,
      currentRef: optionsRefs[option[optionId]],
      activeOption: activeOption,
      makeActive: makeActive,
      optionComponent: optionComponent
    }, option[optionId]))
  });
}
function CheckboxMultiselectTypeahead({
  options,
  optionId,
  optionLabel = 'label',
  items = [],
  isDisabled,
  validity,
  onSelect: onChange = () => {},
  selectAllRow,
  // @ts-expect-error I'm setting this to null explicitly so that Typeahead would not pass default component to CheckboxListItem
  optionComponent = null,
  shouldShowValidityOnTouched = false,
  ...otherMultiSelectTypeaheadProps
}) {
  // multiselect typeahead does not use typeahead logic for rendering validity message,
  // but in its logic it does not do checks on whether input was touched or not
  // didn't want to introduce this to multiselect typeahead component cause not sure if it's needed there,
  // but it is needed in usages of this one.
  const [isTouched, setTouched] = (0, _react.useState)(!!items?.length);
  const allChecked = items.length === options?.length;
  const itemLabels = items?.map(item => {
    const selectedOption = options?.find(optionItem => optionItem[optionId] === item);
    return selectedOption ? selectedOption[optionLabel] : item;
  }) ?? [];
  const modifiedOptions = options?.map(optionItem => ({
    ...optionItem,
    shouldNotCloseDropdown: true,
    isChecked: items?.includes(optionItem[optionId])
  })) ?? [];
  if (modifiedOptions.length && selectAllRow) {
    modifiedOptions.unshift({
      [optionId]: SELECT_ALL_KEY,
      ...selectAllRow,
      shouldNotCloseDropdown: true,
      isChecked: allChecked,
      indeterminate: !!items?.length && items.length < (options?.length ?? 0)
    });
  }
  function onSelect(option) {
    setTouched(true);
    if (option) {
      const id = option[optionId];
      if (id === SELECT_ALL_KEY) {
        // handle select all click
        if (!allChecked) {
          onChange(options?.map(optionItem => optionItem[optionId]));
        } else {
          onChange([]);
        }
      } else if (items.includes(option[optionId])) {
        // toggle selected option
        onChange(items.filter(item => item !== option[optionId]));
      } else {
        // add new selected item
        onChange([...items, option[optionId]]);
      }
    }
  }
  function onDelete(title) {
    setTouched(true);
    const option = options?.find(optionItem => optionItem[optionLabel] === title);
    onChange(items.filter(item => {
      const key = typeof option === 'string' ? option : option?.[optionId];
      return item !== key;
    }));
  }
  let validityValue;
  if (shouldShowValidityOnTouched) {
    validityValue = isTouched ? validity : undefined;
  } else {
    validityValue = validity;
  }
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_multiSelectTypeahead.default, {
    ...otherMultiSelectTypeaheadProps,
    isDisabled: isDisabled,
    showAllOnFocus: true,
    items: itemLabels,
    OptionList: CheckboxOptionList,
    optionComponent: optionComponent,
    options: modifiedOptions,
    optionId: optionId,
    optionLabel: optionLabel,
    onSelect: onSelect,
    onDelete: onDelete,
    onBlur: () => setTouched(true),
    keepInvalidText: true,
    shouldShowSelectedOptions: true,
    validity: validityValue,
    dropdownContentClass: (0, _classnames.default)('checkbox-multiselect-typeahead-dropdown-content', otherMultiSelectTypeaheadProps?.dropdownContentClass)
  });
}