import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import isEmpty from '../../node_modules/lodash-es/isEmpty.js';
import 'core-js/modules/es.symbol.js';
import 'core-js/modules/es.array.concat.js';
import 'core-js/modules/es.array.filter.js';
import 'core-js/modules/es.array.map.js';
import 'core-js/modules/es.function.name.js';
import 'core-js/modules/es.object.get-own-property-descriptor.js';
import 'core-js/modules/es.object.get-own-property-descriptors.js';
import 'core-js/modules/es.object.keys.js';
import 'core-js/modules/es.object.to-string.js';
import 'core-js/modules/web.dom-collections.for-each.js';
import React__default, { useState, useRef, useMemo } from 'react';
import PropTypes from 'prop-types';
import ComposedModal from '../ComposedModal/ComposedModal.js';
import Button from '../Button/Button.js';
import { settings } from '../../constants/Settings.js';
import ListBuilder from '../ListBuilder/ListBuilder.js';
import { ArrowRight, Subtract } from '@carbon/icons-react';

var _excluded = ["addUser", "removeUser", "expand", "close"];
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,
  prefix = settings.prefix;
var UserShape = PropTypes.shape({
  id: PropTypes.string,
  name: PropTypes.string,
  email: PropTypes.string,
  username: PropTypes.string
});
var GroupShape = PropTypes.shape({
  id: PropTypes.string,
  name: PropTypes.string,
  groups: PropTypes.arrayOf(PropTypes.any),
  users: PropTypes.arrayOf(UserShape)
});
var propTypes = {
  i18n: PropTypes.shape({
    modalHeaderTitle: PropTypes.string,
    modalHeaderLabel: PropTypes.string,
    addUser: PropTypes.string,
    removeUser: PropTypes.string,
    recent: PropTypes.string,
    allListSearchPlaceholderText: PropTypes.string,
    selectedListSearchPlaceholderText: PropTypes.string,
    expand: PropTypes.string,
    close: PropTypes.string,
    primaryButtonLabel: PropTypes.string,
    secondaryButtonLabel: PropTypes.string,
    /** (count) => `Items (${count} available)` */
    allListTitle: PropTypes.func,
    /** (count) => `${count} items selected` */
    selectedListTitle: PropTypes.func
  }),
  users: PropTypes.arrayOf(GroupShape).isRequired,
  initialSelectedUsers: PropTypes.arrayOf(GroupShape).isRequired,
  /** Should the dialog be open or not */
  isOpen: PropTypes.bool,
  // eslint-disable-line react/boolean-prop-naming
  /** Close the dialog */
  onClose: PropTypes.func.isRequired,
  /** Callback to submit the dialog/form */
  onSubmit: PropTypes.func,
  testId: PropTypes.string
};
var defaultProps = {
  i18n: {
    modalHeaderTitle: 'Select users',
    modalHeaderLabel: 'Selected users will have edit access',
    addUser: 'Add',
    removeUser: 'Remove',
    recent: 'Recent',
    allListSearchPlaceholderText: 'Enter a value to search all users',
    selectedListSearchPlaceholderText: 'Enter a value to search selected users',
    expand: 'Expand',
    close: 'Close',
    allListTitle: function allListTitle(count) {
      return "Users (".concat(count, " available)");
    },
    selectedListTitle: function selectedListTitle(count) {
      return "".concat(count, " Selected");
    },
    primaryButtonLabel: 'OK',
    secondaryButtonLabel: 'Cancel'
  },
  isOpen: false,
  onSubmit: null,
  testId: 'select-users-modal'
};
var itemsAreEqual = function itemsAreEqual(item1, item2) {
  if (!item1 || !item2) {
    return false;
  }

  // they're exactly the object, like some of the storybook examples
  if (item1 === item2) {
    return true;
  }

  // they have the same ids
  if (item1.id && item2.id && item1.id === item2.id) {
    return true;
  }

  // they have the same email
  if (item1.email && item2.email && item1.email === item2.email) {
    return true;
  }
  return false;
};
var mapUsers = function mapUsers(unmodifiedUsers, _ref) {
  var _ref$parents = _ref.parents,
    parents = _ref$parents === void 0 ? [] : _ref$parents,
    _ref$selectedUsers = _ref.selectedUsers,
    selectedUsers = _ref$selectedUsers === void 0 ? [] : _ref$selectedUsers,
    _ref$depth = _ref.depth,
    depth = _ref$depth === void 0 ? 0 : _ref$depth,
    renderRowActions = _ref.renderRowActions,
    renderDisabledState = _ref.renderDisabledState;
  return unmodifiedUsers.map(function (user) {
    var id = user.id,
      name = user.name,
      username = user.username,
      email = user.email,
      _user$users = user.users,
      users = _user$users === void 0 ? [] : _user$users,
      _user$groups = user.groups,
      groups = _user$groups === void 0 ? [] : _user$groups;
    var mappedGroups = isEmpty(groups) ? [] : mapUsers(groups, {
      depth: depth + 1,
      selectedUsers: selectedUsers,
      parents: [].concat(_toConsumableArray(parents), [user]),
      renderRowActions: renderRowActions,
      renderDisabledState: renderDisabledState
    });
    var mappedUsers = isEmpty(users) ? [] : mapUsers(users, {
      depth: depth + 1,
      selectedUsers: selectedUsers,
      parents: [].concat(_toConsumableArray(parents), [user]),
      renderRowActions: renderRowActions,
      renderDisabledState: renderDisabledState
    });
    var children = mappedGroups.concat(mappedUsers);
    return {
      id: id || email,
      content: {
        value: isEmpty(children) ? name : "".concat(name, " (").concat(children.length, ")"),
        secondaryValue: username,
        tertiaryValue: email,
        rowActions: renderRowActions({
          user: user,
          parents: parents,
          selected: selectedUsers,
          depth: depth
        })
      },
      isCategory: depth === 0 && !isEmpty(children),
      disabled: renderDisabledState({
        user: user,
        parents: parents,
        selected: selectedUsers,
        depth: depth
      }),
      children: children
    };
  });
};
var flattenUsers = function flattenUsers(results, user) {
  return user.children && user.children.length > 0 ? user.children.reduce(flattenUsers, results) : results.concat(user);
};
var SelectUsersModal = function SelectUsersModal(_ref2) {
  var isOpen = _ref2.isOpen,
    _onClose = _ref2.onClose,
    _onSubmit = _ref2.onSubmit,
    users = _ref2.users,
    initialSelectedUsers = _ref2.initialSelectedUsers,
    i18n = _ref2.i18n,
    testId = _ref2.testId;
  var mergedI18n = _objectSpread(_objectSpread({}, defaultProps.i18n), i18n);
  var _useState = useState(initialSelectedUsers),
    _useState2 = _slicedToArray(_useState, 2),
    selectedUsers = _useState2[0],
    setSelectedUsers = _useState2[1];
  var canSaveRef = useRef(false);
  var handleRemove = function handleRemove(row) {
    canSaveRef.current = true;
    setSelectedUsers(selectedUsers.filter(function (s) {
      return s !== row;
    }));
  };
  var handleAdd = function handleAdd(row) {
    var _ref3;
    canSaveRef.current = true;
    setSelectedUsers((_ref3 = [row]).concat.apply(_ref3, _toConsumableArray(selectedUsers)));
  };
  var displayAllUsersList = function displayAllUsersList(unmodifiedUsers) {
    var selection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    return mapUsers(unmodifiedUsers, {
      selectedUsers: selection,
      renderDisabledState: function renderDisabledState(_ref4) {
        var user = _ref4.user,
          selected = _ref4.selected,
          parents = _ref4.parents;
        var isInSelected = selected.filter(function (s) {
          return itemsAreEqual(s, user);
        }).length > 0;
        var isChildOfSelected = selected.filter(function (u) {
          return parents.filter(function (p) {
            return itemsAreEqual(p, u);
          }).length > 0;
        }).length > 0;
        return isInSelected || isChildOfSelected;
      },
      renderRowActions: function renderRowActions(_ref5) {
        var user = _ref5.user,
          selected = _ref5.selected,
          parents = _ref5.parents,
          depth = _ref5.depth;
        var username = user.username;
        var isInSelected = selected.filter(function (s) {
          return itemsAreEqual(s, user);
        }).length > 0;
        var isChildOfSelected = selected.filter(function (u) {
          return parents.filter(function (p) {
            return itemsAreEqual(p, u);
          }).length > 0;
        }).length > 0;

        // Don't render actions on the top level unless it's a user. TODO: is this supposed to support a flat list, too?
        var isCategory = depth === 0 && user && !user.username;
        if (isInSelected || isChildOfSelected || isCategory) {
          return null;
        }
        return function () {
          return [/*#__PURE__*/React__default.createElement(Button, {
            key: "".concat(username, "-list-item-button-").concat(depth),
            style: {
              color: 'black'
            },
            role: "button",
            "aria-label": mergedI18n.addUser,
            renderIcon: ArrowRight,
            hasIconOnly: true,
            kind: "ghost",
            size: "sm",
            onClick: function onClick() {
              return handleAdd(user);
            },
            iconDescription: mergedI18n.addUser
            // TODO: pass testId in v3
            // testId={`${testId}-add-user-button`}
          })];
        };
      }
    });
  };
  var displaySelectedUsersList = function displaySelectedUsersList(unmodifiedUsers) {
    return mapUsers(unmodifiedUsers, {
      renderDisabledState: function renderDisabledState() {
        return false;
      },
      renderRowActions: function renderRowActions(_ref6) {
        var user = _ref6.user,
          depth = _ref6.depth;
        var username = user.username;
        if (depth === 0) {
          return function () {
            return [/*#__PURE__*/React__default.createElement(Button, {
              key: "".concat(username, "-list-item-button-").concat(depth),
              style: {
                color: 'black'
              },
              "aria-label": mergedI18n.removeUser,
              renderIcon: Subtract,
              hasIconOnly: true,
              kind: "ghost",
              size: "sm",
              onClick: function onClick() {
                return handleRemove(user);
              },
              iconDescription: mergedI18n.removeUser
              // TODO: pass testId in v3
              // testId={`${testId}-remove-user-button`}
            })];
          };
        }
        return null;
      }
    });
  };
  var usersList = displayAllUsersList(users, selectedUsers);
  var userCount = useMemo(function () {
    return usersList.reduce(flattenUsers, []).length;
  }, [usersList]);
  var selectedList = displaySelectedUsersList(selectedUsers);
  var addUser = mergedI18n.addUser,
    removeUser = mergedI18n.removeUser,
    expand = mergedI18n.expand,
    close = mergedI18n.close,
    i18nListBuilder = _objectWithoutProperties(mergedI18n, _excluded);
  return /*#__PURE__*/React__default.createElement("div", {
    "data-testid": "".concat(testId, "-container"),
    className: "".concat(iotPrefix, "--select-users-modal")
  }, /*#__PURE__*/React__default.createElement(ComposedModal, {
    isLarge: true,
    footer: {
      isPrimaryButtonDisabled: !canSaveRef.current,
      primaryButtonLabel: mergedI18n.primaryButtonLabel,
      secondaryButtonLabel: mergedI18n.secondaryButtonLabel
    },
    header: {
      label: mergedI18n.modalHeaderLabel,
      title: mergedI18n.modalHeaderTitle
    },
    open: isOpen,
    onSubmit: function onSubmit() {
      _onSubmit(selectedUsers);
      canSaveRef.current = false;
    },
    onClose: function onClose(e) {
      setSelectedUsers(initialSelectedUsers);
      _onClose(e);
      canSaveRef.current = false;
    },
    "data-testid": "".concat(testId, "--select-users-modal"),
    selectorPrimaryFocus: ".".concat(prefix, "--modal-header")
  }, /*#__PURE__*/React__default.createElement(ListBuilder, {
    items: usersList,
    itemCount: userCount,
    "data-testid": "".concat(testId, "--select-users-list"),
    testId: "select-users",
    selectedItems: selectedList,
    i18n: _objectSpread(_objectSpread({}, i18nListBuilder), {}, {
      addLabel: addUser,
      removeLabel: removeUser,
      expandIconDescription: expand,
      collapseIconDescription: close
    })
  })));
};
SelectUsersModal.propTypes = propTypes;
SelectUsersModal.defaultProps = defaultProps;
SelectUsersModal.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "SelectUsersModal",
  "props": {
    "i18n": {
      "defaultValue": {
        "value": "{\n  modalHeaderTitle: 'Select users',\n  modalHeaderLabel: 'Selected users will have edit access',\n  addUser: 'Add',\n  removeUser: 'Remove',\n  recent: 'Recent',\n  allListSearchPlaceholderText: 'Enter a value to search all users',\n  selectedListSearchPlaceholderText: 'Enter a value to search selected users',\n  expand: 'Expand',\n  close: 'Close',\n  allListTitle: (count) => `Users (${count} available)`,\n  selectedListTitle: (count) => `${count} Selected`,\n  primaryButtonLabel: 'OK',\n  secondaryButtonLabel: 'Cancel',\n}",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "shape",
        "value": {
          "modalHeaderTitle": {
            "name": "string",
            "required": false
          },
          "modalHeaderLabel": {
            "name": "string",
            "required": false
          },
          "addUser": {
            "name": "string",
            "required": false
          },
          "removeUser": {
            "name": "string",
            "required": false
          },
          "recent": {
            "name": "string",
            "required": false
          },
          "allListSearchPlaceholderText": {
            "name": "string",
            "required": false
          },
          "selectedListSearchPlaceholderText": {
            "name": "string",
            "required": false
          },
          "expand": {
            "name": "string",
            "required": false
          },
          "close": {
            "name": "string",
            "required": false
          },
          "primaryButtonLabel": {
            "name": "string",
            "required": false
          },
          "secondaryButtonLabel": {
            "name": "string",
            "required": false
          },
          "allListTitle": {
            "name": "func",
            "description": "(count) => `Items (${count} available)`",
            "required": false
          },
          "selectedListTitle": {
            "name": "func",
            "description": "(count) => `${count} items selected`",
            "required": false
          }
        }
      },
      "required": false
    },
    "isOpen": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "Should the dialog be open or not",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "onSubmit": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "Callback to submit the dialog/form",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "testId": {
      "defaultValue": {
        "value": "'select-users-modal'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "users": {
      "description": "",
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "custom",
          "raw": "GroupShape"
        }
      },
      "required": true
    },
    "initialSelectedUsers": {
      "description": "",
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "custom",
          "raw": "GroupShape"
        }
      },
      "required": true
    },
    "onClose": {
      "description": "Close the dialog",
      "type": {
        "name": "func"
      },
      "required": true
    }
  }
};
var SelectUsersModal$1 = SelectUsersModal;

export { GroupShape, UserShape, SelectUsersModal$1 as default, propTypes };
