"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.KeyValuePairs = void 0;
var _react = _interopRequireWildcard(require("react"));
var _isEqual = _interopRequireDefault(require("lodash-es/isEqual"));
var _sortBy = _interopRequireDefault(require("lodash-es/sortBy"));
var _classnames = _interopRequireDefault(require("classnames"));
var _faPlus = require("@fortawesome/free-solid-svg-icons/faPlus");
var _button = require("../button");
var _infoIcon = require("../info-icon");
var _formField = require("../form-field");
var _message = require("../message");
var _keyValueInputs = require("./key-value-inputs");
var _useTranslation = require("../hooks/use-translation");
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); }
function useKVPsValidation(hasWarning, warningMessage, defaultValue) {
  const [validity, setValidity] = (0, _react.useState)(defaultValue);
  (0, _react.useEffect)(() => {
    if (hasWarning) {
      setValidity({
        type: _message.MESSAGE_TYPES.WARNING,
        value: warningMessage
      });
    } else {
      setValidity(defaultValue);
    }
  }, [hasWarning]);
  return [validity, setValidity];
}
function extractObjToArray(val = {}) {
  return Object.entries(val).map(([key, value]) => {
    return {
      name: key,
      value
    };
  });
}
const SUCCESSFUL_VALIDATION_OBJ = {
  type: _message.MESSAGE_TYPES.SUCCESS,
  value: ''
};
const removeEmptyPairs = ({
  name,
  value
}) => !!name && !!value;
const removeDuplicateKeys = ({
  name
}, index, collection) => collection.findIndex(item => item.name === name) === index;
const sortItems = items => (0, _sortBy.default)(items, ['name', 'value']);
/** Key Value Pairs
    @midnight-gray-supported
    @alpine-light-supported
 */
const KeyValuePairs = ({
  value,
  className = '',
  label = '',
  keyLabel = '',
  valueLabel = '',
  helperText = '',
  placeholder: placeholderParams,
  isDisabled = false,
  disabledPairs,
  onChange = () => {},
  hasWarning = false,
  emptyCheck = false,
  warningMessage: warningMessageParams,
  buttonText: buttonTextParams,
  maxItemsTooltipText: maxItemsTooltipTextParams,
  emptyItemErrorText: emptyItemErrorTextParams,
  deleteKeyValueText: deleteKeyValueTextParams,
  buildDuplicateItemErrorText: buildDuplicateItemErrorTextParams,
  testId = 'key-value-pairs',
  infoIconProps = null,
  onError = () => {},
  maxSize = null,
  addButtonAccentType = _button.ACCENT_TYPES.COMMAND,
  keyInputAriaLabel: keyInputAriaLabelParams,
  valueInputAriaLabel: valueInputAriaLabelParams,
  id = ''
}) => {
  const {
    t
  } = (0, _useTranslation.useTranslation)();
  const placeholder = placeholderParams ?? t('No items found');
  const buttonText = buttonTextParams ?? t('Add item');
  const maxItemsTooltipText = maxItemsTooltipTextParams ?? t('Max number of key-value pairs reached');
  const emptyItemErrorText = emptyItemErrorTextParams ?? t('Above field(s) should not be empty');
  const deleteKeyValueText = deleteKeyValueTextParams ?? t('Delete');
  const keyInputAriaLabel = keyInputAriaLabelParams ?? t('Key input');
  const valueInputAriaLabel = valueInputAriaLabelParams ?? t('Value input');
  const warningMessage = warningMessageParams ?? t('Double-check this value');
  const buildDuplicateItemErrorText = buildDuplicateItemErrorTextParams ?? (({
    name
  }) => t('Duplicated keys ({{name}}) are not allowed.', {
    name
  }));
  // Keep items in array format to ensure duplicate objects CAN be shown (but are not valid)
  const [items, setItems] = (0, _react.useState)(extractObjToArray(value));
  const lastInputRef = (0, _react.useRef)(null);
  const [validity, setValidity] = useKVPsValidation(hasWarning, warningMessage, SUCCESSFUL_VALIDATION_OBJ);
  (0, _react.useEffect)(() => {
    // Adjust `items` if new `value` passed in
    // is different from what is already in `items`
    // (with empty KVPs filtered out).
    //
    // Note: Sort both, since order of object `value` is not guaranteed.
    const sortedOldItems = sortItems(items).filter(removeEmptyPairs).filter(removeDuplicateKeys);
    const newItems = extractObjToArray(value);
    const sortedNewItems = sortItems(newItems);
    if (!(0, _isEqual.default)(sortedOldItems, sortedNewItems)) {
      setItems(newItems);
      setValidity(SUCCESSFUL_VALIDATION_OBJ);
    }
  }, [value]);
  function handleChange(updatedItems) {
    let isValid = true;
    const validationResults = updatedItems.reduce((processedItems, item) => {
      const cleanedName = typeof item.name === 'string' ? item.name.trim() : item.name;
      const cleanedValue = typeof item.value === 'string' ? item.value.trim() : item.value;
      const hasKey = cleanedName !== '';
      if (emptyCheck && !(cleanedName && cleanedValue !== undefined && cleanedValue !== '')) {
        setValidity({
          type: _message.MESSAGE_TYPES.ERROR,
          value: emptyItemErrorText
        });
        isValid = false;
      } else if (cleanedName in processedItems && hasKey) {
        setValidity({
          type: _message.MESSAGE_TYPES.ERROR,
          value: buildDuplicateItemErrorText({
            name: cleanedName
          })
        });
        isValid = false;
      }
      processedItems[cleanedName] = item.value;
      return processedItems;
    }, {});
    if (isValid) {
      setValidity(SUCCESSFUL_VALIDATION_OBJ);
      onChange(validationResults);
    } else {
      onError(value);
    }
  }
  function handleUpdateItems(updatedItems, addNewItem = false) {
    setItems(updatedItems);
    if (!addNewItem) {
      handleChange(updatedItems);
    }
  }
  function removeItem(index) {
    const updatedItems = items.filter((option, i) => i !== index);
    handleUpdateItems(updatedItems);
  }
  function addItem() {
    const updatedItems = [...items, {
      name: '',
      value: ''
    }];
    handleUpdateItems(updatedItems, true);
    setTimeout(() => {
      lastInputRef?.current?.focus();
    }, 0);
  }
  function changeItem(index, updatedItem) {
    const updatedItems = [...items];
    if (updatedItems[index]) {
      updatedItems[index] = updatedItem;
      handleUpdateItems(updatedItems);
    }
  }
  const elements = items.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
    className: "kvp-no-text",
    children: placeholder
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [(keyLabel || valueLabel) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
      className: "kvp-inputs",
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
        className: "key-input",
        children: keyLabel
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
        className: "value-input",
        children: valueLabel
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
        className: "kvp-inputs-empty-block"
      })]
    }), items.map((item, index) => {
      const paddedIndex = index + 1;
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_keyValueInputs.KeyValueInputs, {
        validity: validity,
        name: item.name,
        value: item.value,
        isDisabled: isDisabled,
        disabledPairs: disabledPairs,
        onChange: updatedOption => changeItem(index, updatedOption),
        onDelete: () => removeItem(index),
        deleteKeyValueText: `${deleteKeyValueText} ${paddedIndex}`,
        keyLabel: keyLabel,
        valueLabel: valueLabel,
        keyInputAriaLabel: `${keyInputAriaLabel} ${paddedIndex}`,
        valueInputAriaLabel: `${valueInputAriaLabel} ${paddedIndex}`,
        id: id,
        ref: index === items.length - 1 ? lastInputRef : null
      }, index);
    })]
  });
  const maxKVPsLimitReached = !!maxSize && items.length >= maxSize;
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    "test-id": testId,
    className: (0, _classnames.default)('kvps-container', className),
    children: [label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_formField.FormFieldLabel, {
      label: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
        children: [label, infoIconProps && /*#__PURE__*/(0, _jsxRuntime.jsx)(_infoIcon.InfoIcon, {
          ...infoIconProps
        })]
      }),
      labelTestId: `${testId}-dr-field-label`,
      isDisabled: isDisabled
    }), helperText && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: "margin-bottom-2 kvp-items-helper-text",
      children: helperText
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: "kvps-items",
      children: elements
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: "kvps-form-controls",
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
        testId: `${testId}-add-button`,
        accentType: addButtonAccentType,
        leftIcon: _faPlus.faPlus,
        isDisabled: isDisabled || maxKVPsLimitReached,
        tooltipText: maxKVPsLimitReached ? maxItemsTooltipText : null,
        onClick: addItem,
        children: buttonText
      })
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_formField.ValidityMessages, {
      validity: validity,
      fieldId: id,
      validationTestId: "key-value-pair-validity"
    })]
  });
};
exports.KeyValuePairs = KeyValuePairs;