import _extends from '@babel/runtime/helpers/extends';
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
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, { useMemo, useCallback } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Tabs, TabList, Tab, TabPanels, TabPanel, Accordion, AccordionItem, TextInput, Tag } from '@carbon/react';
import { settings } from '../../constants/Settings.js';
import { ToolbarSVGWrapper } from '../Card/CardToolbar.js';
import Button from '../Button/Button.js';
import FilterTags from '../FilterTags/FilterTags.js';
import SelectUsersModal from '../SelectUsersModal/SelectUsersModal.js';
import StatefulTable from '../Table/StatefulTable.js';
import RuleBuilderTags from './RuleBuilderTags.js';
import RuleBuilderEditor from './RuleBuilderEditor.js';
import { RuleBuilderFilterPropType } from './RuleBuilderPropTypes.js';
import { Add } from '@carbon/icons-react';

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;
var propTypes = {
  className: PropTypes.string,
  /** Text for main tilte of page */
  defaultTitleText: PropTypes.string,
  /** Text for metadata for the filter */
  // metaText: PropTypes.string,
  /** Unique id for particular filter */
  // id: PropTypes.string,
  /**
   * Optional action buttons at top of page and callbacks to handle actions
   */
  actionBar: PropTypes.arrayOf(PropTypes.shape({
    actionId: PropTypes.string.isRequired,
    actionLabel: PropTypes.string.isRequired,
    actionIcon: PropTypes.elementType.isRequired,
    actionCallback: PropTypes.func.isRequired
  })),
  onSave: PropTypes.func.isRequired,
  onCancel: PropTypes.func.isRequired,
  /** Optional rule editor component to overwrite the default */
  ruleEditor: PropTypes.elementType,
  /** filter object of the current selected filter */
  filter: RuleBuilderFilterPropType,
  /**
   * Optional footer buttons and callbacks to handle actions
   */
  footerButtons: PropTypes.arrayOf(PropTypes.shape({
    buttonId: PropTypes.string.isRequired,
    buttonLabel: PropTypes.string.isRequired,
    buttonCallback: PropTypes.func.isRequired
  })),
  onChange: PropTypes.func,
  i18n: PropTypes.shape({
    addUsers: PropTypes.string,
    editorAccess: PropTypes.string,
    readOnlyAccess: PropTypes.string,
    sharingAndPermissions: PropTypes.string,
    filterTabText: PropTypes.string,
    sharingTabText: PropTypes.string,
    clearFilterTitle: PropTypes.string,
    saveLabel: PropTypes.string,
    cancelLabel: PropTypes.string
  }),
  testId: PropTypes.string
};
var defaultProps = {
  filter: {
    filterTags: [],
    filterAccess: [],
    filterUsers: []
  },
  className: null,
  defaultTitleText: 'Undefined',
  // metaText: null,
  // id: null,
  ruleEditor: null,
  actionBar: null,
  footerButtons: null,
  onChange: function onChange() {},
  i18n: {
    addUsersButtonLabel: 'Add users',
    editorAccessLabel: 'Editor access',
    readOnlyAccessLabel: 'Read only access',
    detailsAccordionText: 'Details',
    sharingAccordionText: 'Sharing and permissions',
    filterTabText: 'Filter builder',
    sharingTabText: 'Sharing and preferences',
    filterNameLabel: 'Filter Name',
    tagsLabel: 'Tags (optional)',
    clearFilterTitle: 'Clear Filter',
    saveLabel: 'Save',
    cancelLabel: 'Cancel',
    readModalHeaderLabel: "Selected users will have read access",
    editModalHeaderLabel: "Selected users will have edit access",
    nameColumnLabel: 'Name',
    typeColumnLabel: 'Type',
    groupTypeLabel: 'Group',
    userTypeLabel: 'User',
    modalPrimaryButtonLabel: 'OK'
  },
  testId: 'rule-builder'
};
var baseClass = "".concat(iotPrefix, "--rule-builder-wrap");
var RuleBuilder = function RuleBuilder(_ref) {
  var _currentFilter$filter6, _currentFilter$filter7, _currentFilter$filter8;
  var className = _ref.className,
    defaultTitleText = _ref.defaultTitleText,
    onSave = _ref.onSave,
    onCancel = _ref.onCancel,
    actionBar = _ref.actionBar,
    footerButtons = _ref.footerButtons,
    filter = _ref.filter,
    RuleEditor = _ref.ruleEditor,
    onChange = _ref.onChange,
    i18n = _ref.i18n,
    testId = _ref.testId;
  var _React$useState = React__default.useState(filter),
    _React$useState2 = _slicedToArray(_React$useState, 2),
    currentFilter = _React$useState2[0],
    setCurrentFilter = _React$useState2[1];
  var _React$useState3 = React__default.useState({
      isOpen: false,
      access: 'READ'
    }),
    _React$useState4 = _slicedToArray(_React$useState3, 2),
    modalState = _React$useState4[0],
    setModalState = _React$useState4[1];
  var mergedI18n = useMemo(function () {
    return _objectSpread(_objectSpread({}, defaultProps.i18n), i18n);
  }, [i18n]);
  var Editor = useMemo(function () {
    return RuleEditor || RuleBuilderEditor;
  }, [RuleEditor]);
  var actions = useMemo(function () {
    return actionBar === null || actionBar === void 0 ? void 0 : actionBar.map(function (i) {
      return /*#__PURE__*/React__default.createElement(ToolbarSVGWrapper, {
        key: i.actionId,
        testId: i.actionId,
        title: i.actionLabel,
        onClick: function onClick() {
          i.actionCallback(currentFilter);
        },
        iconDescription: i.actionLabel,
        renderIcon: i.actionIcon
      });
    });
  }, [actionBar, currentFilter]);
  var footer = useMemo(function () {
    return footerButtons === null || footerButtons === void 0 ? void 0 : footerButtons.map(function (i) {
      return /*#__PURE__*/React__default.createElement(Button, {
        testId: i.buttonId,
        key: i.buttonId,
        kind: "secondary",
        className: "".concat(baseClass, "--footer-actions-preview"),
        onClick: function onClick() {
          i.buttonCallback(currentFilter);
        }
      }, i.buttonLabel);
    });
  }, [currentFilter, footerButtons]);
  var handleOnChange = function handleOnChange(update, type) {
    var _currentFilter$filter;
    var updatedFilter;
    switch (type) {
      case 'TITLE':
        updatedFilter = {
          filterTitleText: update
        };
        break;
      case 'TAGS':
        updatedFilter = {
          filterTags: [].concat(_toConsumableArray((_currentFilter$filter = currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterTags) !== null && _currentFilter$filter !== void 0 ? _currentFilter$filter : []), [update])
        };
        break;
      default:
        updatedFilter = {
          filterRules: update
        };
    }
    setCurrentFilter(function (current) {
      return _objectSpread(_objectSpread({}, current), updatedFilter);
    });
    onChange(updatedFilter);
  };
  var handleAddAccess = useCallback(function (access) {
    return function () {
      setModalState({
        access: access,
        isOpen: true
      });
    };
  }, [setModalState]);
  var handleCloseModal = useCallback(function () {
    setModalState(_objectSpread(_objectSpread({}, modalState), {}, {
      isOpen: false
    }));
  }, [modalState]);
  var handleTagClose = useCallback(function (tag) {
    return function () {
      setCurrentFilter(function (prev) {
        return _objectSpread(_objectSpread({}, prev), {}, {
          filterTags: prev.filterTags.filter(function (t) {
            return t !== tag;
          })
        });
      });
    };
  }, []);
  var editUsers = useMemo(function () {
    var _currentFilter$filter2, _currentFilter$filter3;
    return (_currentFilter$filter2 = currentFilter === null || currentFilter === void 0 || (_currentFilter$filter3 = currentFilter.filterAccess) === null || _currentFilter$filter3 === void 0 ? void 0 : _currentFilter$filter3.filter(function (user) {
      return user.access === 'edit';
    })) !== null && _currentFilter$filter2 !== void 0 ? _currentFilter$filter2 : [];
  }, [currentFilter]);
  var readUsers = useMemo(function () {
    var _currentFilter$filter4, _currentFilter$filter5;
    return (_currentFilter$filter4 = currentFilter === null || currentFilter === void 0 || (_currentFilter$filter5 = currentFilter.filterAccess) === null || _currentFilter$filter5 === void 0 ? void 0 : _currentFilter$filter5.filter(function (user) {
      return user.access === 'read';
    })) !== null && _currentFilter$filter4 !== void 0 ? _currentFilter$filter4 : [];
  }, [currentFilter]);
  var handleUserSelect = useCallback(function (access) {
    return function (selectedUsers) {
      setModalState(function (prev) {
        return _objectSpread(_objectSpread({}, prev), {}, {
          isOpen: false
        });
      });
      setCurrentFilter(function (prev) {
        var _prev$filterAccess$fi, _prev$filterAccess;
        return _objectSpread(_objectSpread({}, prev), {}, {
          filterAccess: [].concat(_toConsumableArray((_prev$filterAccess$fi = (_prev$filterAccess = prev.filterAccess) === null || _prev$filterAccess === void 0 ? void 0 : _prev$filterAccess.filter(function (user) {
            return user.access !== access;
          })) !== null && _prev$filterAccess$fi !== void 0 ? _prev$filterAccess$fi : []), _toConsumableArray(selectedUsers.map(function (user) {
            return _objectSpread(_objectSpread({}, user), {}, {
              access: access
            });
          })))
        });
      });
    };
  }, []);
  return /*#__PURE__*/React__default.createElement("section", {
    className: classnames(baseClass, className),
    id: currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.id
    // TODO: change this to use only testId in v3.
    ,
    "data-testid": (currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.id) || testId
  }, /*#__PURE__*/React__default.createElement("header", {
    className: "".concat(baseClass, "--header")
  }, /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("h1", {
    className: "".concat(baseClass, "--header-title"),
    "data-testid": "".concat(testId, "-title")
  }, (currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterTitleText) || defaultTitleText), (currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterMetaText) && /*#__PURE__*/React__default.createElement("p", {
    "data-testid": "".concat(testId, "-metatext"),
    className: "".concat(baseClass, "--header-metatext")
  }, currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterMetaText)), /*#__PURE__*/React__default.createElement("div", {
    className: "".concat(baseClass, "--header-actions")
  }, actions, /*#__PURE__*/React__default.createElement(Button, {
    className: "".concat(baseClass, "--header-actions-save"),
    testId: "rule-builder-save",
    onClick: function onClick() {
      return onSave(currentFilter);
    },
    size: "sm"
  }, mergedI18n.saveLabel))), /*#__PURE__*/React__default.createElement("div", {
    className: "".concat(baseClass, "--body")
  }, /*#__PURE__*/React__default.createElement(Tabs, {
    "data-testid": "".concat(testId, "-tabs"),
    className: "".concat(baseClass, "--tabs")
  }, /*#__PURE__*/React__default.createElement(TabList, {
    "aria-label": "List of tabs"
  }, /*#__PURE__*/React__default.createElement(Tab, {
    className: "".concat(baseClass, "--tab"),
    "data-testid": "".concat(testId, "-editor-tab")
  }, mergedI18n.filterTabText), /*#__PURE__*/React__default.createElement(Tab, {
    className: "".concat(baseClass, "--tab"),
    "data-testid": "".concat(testId, "-sharing-tab")
  }, mergedI18n.sharingTabText)), /*#__PURE__*/React__default.createElement(TabPanels, null, /*#__PURE__*/React__default.createElement(TabPanel, null, /*#__PURE__*/React__default.createElement(Editor, {
    defaultRules: currentFilter.filterRules,
    columns: currentFilter.filterColumns,
    onChange: handleOnChange,
    testId: "".concat(testId, "-editor")
  })), /*#__PURE__*/React__default.createElement(TabPanel, null, /*#__PURE__*/React__default.createElement(Accordion, null, /*#__PURE__*/React__default.createElement(AccordionItem, {
    title: mergedI18n.detailsAccordionText,
    open: true
  }, /*#__PURE__*/React__default.createElement(TextInput, {
    type: "text",
    id: "rule-builder-title-input",
    className: "".concat(baseClass, "--title-input"),
    labelText: mergedI18n.filterNameLabel,
    light: true,
    defaultValue: currentFilter.filterTitleText,
    placeholder: "Untitled 01",
    onChange: function onChange(e) {
      return handleOnChange(e.target.value, 'TITLE');
    },
    "data-testid": "".concat(testId, "-title-input")
  }), /*#__PURE__*/React__default.createElement(FilterTags, {
    hasOverflow: true,
    tagContainer: RuleBuilderTags,
    onChange: handleOnChange,
    i18n: mergedI18n,
    testId: "".concat(testId, "-tags")
  }, (currentFilter === null || currentFilter === void 0 || (_currentFilter$filter6 = currentFilter.filterTags) === null || _currentFilter$filter6 === void 0 ? void 0 : _currentFilter$filter6.map(function (tag) {
    return /*#__PURE__*/React__default.createElement(Tag, {
      key: "tag-".concat(tag),
      filter: true,
      title: mergedI18n.clearFilterTitle,
      style: {
        marginRight: '1rem'
      },
      onClose: handleTagClose(tag),
      "data-testid": "".concat(testId, "-tag-").concat(tag)
    }, tag);
  })) || [])), /*#__PURE__*/React__default.createElement(AccordionItem, {
    title: mergedI18n.sharingAccordionText,
    open: true
  }, /*#__PURE__*/React__default.createElement("div", {
    className: "".concat(baseClass, "--user-container")
  }, /*#__PURE__*/React__default.createElement(StatefulTable, {
    id: "edit-table",
    testId: "".concat(testId, "-edit-users-table"),
    secondaryTitle: mergedI18n.editorAccessLabel,
    options: {
      hasSearch: true
    },
    view: {
      toolbar: {
        customToolbarContent: /*#__PURE__*/React__default.createElement(Button, {
          "aria-labelledby": "add-editors-label",
          renderIcon: function renderIcon(props) {
            return /*#__PURE__*/React__default.createElement(Add, _extends({
              size: 16
            }, props));
          },
          id: "add-editors-button",
          kind: "ghost",
          testId: "rule-builder-add-edit-users",
          onClick: handleAddAccess('edit')
        }, mergedI18n.addUsersButtonLabel)
      },
      table: {}
    },
    data: editUsers.map(function (user) {
      return {
        id: user.name,
        values: {
          name: user.name,
          type: Array.isArray(user.users) && user.users.length > 0 ? mergedI18n.groupTypeLabel : mergedI18n.userTypeLabel
        }
      };
    }),
    columns: [{
      id: 'name',
      name: mergedI18n.nameColumnLabel
    }, {
      id: 'type',
      name: mergedI18n.typeColumnLabel
    }]
  }), /*#__PURE__*/React__default.createElement(StatefulTable, {
    id: "read-table",
    testId: "".concat(testId, "-read-users-table"),
    secondaryTitle: mergedI18n.readOnlyAccessLabel,
    options: {
      hasSearch: true
    },
    view: {
      toolbar: {
        customToolbarContent: /*#__PURE__*/React__default.createElement(Button, {
          "aria-labelledby": "read-only-access-label",
          renderIcon: function renderIcon(props) {
            return /*#__PURE__*/React__default.createElement(Add, _extends({
              size: 16
            }, props));
          },
          id: "add-read-users",
          kind: "ghost",
          testId: "rule-builder-add-read-users",
          onClick: handleAddAccess('read')
        }, mergedI18n.addUsersButtonLabel)
      },
      table: {}
    },
    data: readUsers.map(function (user) {
      return {
        id: user.name,
        values: {
          name: user.name,
          type: Array.isArray(user.users) && user.users.length > 0 ? mergedI18n.groupTypeLabel : mergedI18n.userTypeLabel
        }
      };
    }),
    columns: [{
      id: 'name',
      name: mergedI18n.nameColumnLabel
    }, {
      id: 'type',
      name: mergedI18n.typeColumnLabel
    }]
  })))))))), /*#__PURE__*/React__default.createElement("footer", {
    className: "".concat(baseClass, "--footer")
  }, /*#__PURE__*/React__default.createElement(Button, {
    kind: "secondary",
    className: "".concat(baseClass, "--footer-actions-cancel"),
    testId: "rule-builder-cancel",
    onClick: onCancel
  }, mergedI18n.cancelLabel), footer), /*#__PURE__*/React__default.createElement(SelectUsersModal, {
    users: (_currentFilter$filter7 = currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterUsers) !== null && _currentFilter$filter7 !== void 0 ? _currentFilter$filter7 : [],
    i18n: {
      modalHeaderLabel: mergedI18n.editModalHeaderLabel,
      primaryButtonLabel: mergedI18n.modalPrimaryButtonLabel
    },
    initialSelectedUsers: editUsers,
    onSubmit: handleUserSelect('edit'),
    onClose: handleCloseModal,
    isOpen: modalState.isOpen && modalState.access === 'edit'
  }), /*#__PURE__*/React__default.createElement(SelectUsersModal, {
    users: (_currentFilter$filter8 = currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.filterUsers) !== null && _currentFilter$filter8 !== void 0 ? _currentFilter$filter8 : [],
    i18n: {
      modalHeaderLabel: mergedI18n.readModalHeaderLabel,
      primaryButtonLabel: mergedI18n.modalPrimaryButtonLabel
    },
    initialSelectedUsers: readUsers,
    onSubmit: handleUserSelect('read'),
    onClose: handleCloseModal,
    isOpen: modalState.isOpen && modalState.access === 'read'
  }));
};
RuleBuilder.propTypes = propTypes;
RuleBuilder.defaultProps = defaultProps;
RuleBuilder.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "RuleBuilder",
  "props": {
    "filter": {
      "defaultValue": {
        "value": "{\n  filterTags: [],\n  filterAccess: [],\n  filterUsers: [],\n}",
        "computed": false
      },
      "description": "filter object of the current selected filter",
      "type": {
        "name": "custom",
        "raw": "RuleBuilderFilterPropType"
      },
      "required": false
    },
    "className": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "defaultTitleText": {
      "defaultValue": {
        "value": "'Undefined'",
        "computed": false
      },
      "description": "Text for main tilte of page",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "ruleEditor": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "Optional rule editor component to overwrite the default",
      "type": {
        "name": "elementType"
      },
      "required": false
    },
    "actionBar": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "Optional action buttons at top of page and callbacks to handle actions",
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "shape",
          "value": {
            "actionId": {
              "name": "string",
              "required": true
            },
            "actionLabel": {
              "name": "string",
              "required": true
            },
            "actionIcon": {
              "name": "elementType",
              "required": true
            },
            "actionCallback": {
              "name": "func",
              "required": true
            }
          }
        }
      },
      "required": false
    },
    "footerButtons": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "Optional footer buttons and callbacks to handle actions",
      "type": {
        "name": "arrayOf",
        "value": {
          "name": "shape",
          "value": {
            "buttonId": {
              "name": "string",
              "required": true
            },
            "buttonLabel": {
              "name": "string",
              "required": true
            },
            "buttonCallback": {
              "name": "func",
              "required": true
            }
          }
        }
      },
      "required": false
    },
    "onChange": {
      "defaultValue": {
        "value": "() => {}",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "i18n": {
      "defaultValue": {
        "value": "{\n  addUsersButtonLabel: 'Add users',\n  editorAccessLabel: 'Editor access',\n  readOnlyAccessLabel: 'Read only access',\n  detailsAccordionText: 'Details',\n  sharingAccordionText: 'Sharing and permissions',\n  filterTabText: 'Filter builder',\n  sharingTabText: 'Sharing and preferences',\n  filterNameLabel: 'Filter Name',\n  tagsLabel: 'Tags (optional)',\n  clearFilterTitle: 'Clear Filter',\n  saveLabel: 'Save',\n  cancelLabel: 'Cancel',\n  readModalHeaderLabel: `Selected users will have read access`,\n  editModalHeaderLabel: `Selected users will have edit access`,\n  nameColumnLabel: 'Name',\n  typeColumnLabel: 'Type',\n  groupTypeLabel: 'Group',\n  userTypeLabel: 'User',\n  modalPrimaryButtonLabel: 'OK',\n}",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "shape",
        "value": {
          "addUsers": {
            "name": "string",
            "required": false
          },
          "editorAccess": {
            "name": "string",
            "required": false
          },
          "readOnlyAccess": {
            "name": "string",
            "required": false
          },
          "sharingAndPermissions": {
            "name": "string",
            "required": false
          },
          "filterTabText": {
            "name": "string",
            "required": false
          },
          "sharingTabText": {
            "name": "string",
            "required": false
          },
          "clearFilterTitle": {
            "name": "string",
            "required": false
          },
          "saveLabel": {
            "name": "string",
            "required": false
          },
          "cancelLabel": {
            "name": "string",
            "required": false
          }
        }
      },
      "required": false
    },
    "testId": {
      "defaultValue": {
        "value": "'rule-builder'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "onSave": {
      "description": "",
      "type": {
        "name": "func"
      },
      "required": true
    },
    "onCancel": {
      "description": "",
      "type": {
        "name": "func"
      },
      "required": true
    }
  }
};
var RuleBuilder$1 = RuleBuilder;

export { RuleBuilder$1 as default };
