import _extends from "@babel/runtime/helpers/extends";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["error", "defaultSelection", "validator", "onChange", "onBlur", "onFocus", "id", "suggestions", "renderSuggestion", "warning", "menuFullWidth", "disableRemovalOfFirst"];

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

import cx from 'classnames';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import Box from '../box';
import ValidationText from '../validationText';
import Label from './Label';
import theme from './theme.css';
import { excludeSuggestions } from './utils';

var EmailSelector = function EmailSelector(_ref) {
  var _cx;

  var error = _ref.error,
      defaultSelection = _ref.defaultSelection,
      validator = _ref.validator,
      onChange = _ref.onChange,
      onBlur = _ref.onBlur,
      onFocus = _ref.onFocus,
      id = _ref.id,
      suggestions = _ref.suggestions,
      renderSuggestion = _ref.renderSuggestion,
      warning = _ref.warning,
      menuFullWidth = _ref.menuFullWidth,
      disableRemovalOfFirst = _ref.disableRemovalOfFirst,
      rest = _objectWithoutProperties(_ref, _excluded);

  var ref = useRef(null);
  var inputRef = useRef(null);
  var validateLabel = useCallback(function (option) {
    return _objectSpread(_objectSpread({}, option), {}, {
      valid: validator ? validator(option) === true : undefined
    });
  }, [validator]);

  var _useState = useState(Array.isArray(defaultSelection) ? defaultSelection.map(validateLabel) : []),
      _useState2 = _slicedToArray(_useState, 2),
      selection = _useState2[0],
      setSelection = _useState2[1];

  var _useState3 = useState(null),
      _useState4 = _slicedToArray(_useState3, 2),
      editingLabel = _useState4[0],
      setEditingLabel = _useState4[1];

  var _useState5 = useState(false),
      _useState6 = _slicedToArray(_useState5, 2),
      internalWarning = _useState6[0],
      setInternalWarning = _useState6[1];

  var validSuggestions = useMemo(function () {
    if (!suggestions) {
      return [];
    }

    return excludeSuggestions(selection, suggestions);
  }, [suggestions, selection]);
  var changeHandler = useCallback(function (selection) {
    onChange && onChange(selection.filter(function (selection) {
      return selection.email.trim() !== '';
    }));
  }, [onChange]);
  var onLabelClick = useCallback(function (index) {
    !disableRemovalOfFirst && setEditingLabel(index);
    setSelection(selection.filter(function (selection, i) {
      return i <= index || selection.email.trim() !== '';
    }));
  }, [setEditingLabel, setSelection, selection]);

  var createNewLabel = function createNewLabel(selection) {
    var newSelection = selection.filter(function (selection) {
      return selection.email.trim() !== '';
    });
    newSelection.push({
      email: ''
    });
    setSelection(newSelection);
    setEditingLabel(newSelection.length - 1);
  };

  var onUpdateLabel = useCallback(function (index, newLabel) {
    var newSelection = _toConsumableArray(selection);

    if (!newLabel || newLabel.email.trim() === '') {
      newSelection.splice(index, 1);
      setSelection(newSelection);
      setEditingLabel(null);
      onBlur && onBlur();
    } else {
      var result = validator ? validator(newLabel) : true;

      if (result === false) {
        setInternalWarning(true);
        return false;
      }

      if (typeof result === 'string') {
        setInternalWarning(result);
        return false;
      }

      newSelection.splice(index, 1, validateLabel(newLabel));
      createNewLabel(newSelection);
    }

    setInternalWarning(false);
    changeHandler(newSelection);
    return true;
  }, [selection, changeHandler, onBlur, validator, validateLabel]);
  var onBlurLabel = useCallback(function (index, newLabel) {
    var newSelection = _toConsumableArray(selection);

    if (!newLabel || newLabel.email.trim() === '') {
      newSelection.splice(index, 1);
    } else {
      newSelection.splice(index, 1, validateLabel(newLabel));
    }

    setInternalWarning(false);
    setSelection(newSelection);
    setEditingLabel(null);
    onBlur && onBlur();
    changeHandler(newSelection);
  }, [selection, onBlur, changeHandler, validateLabel]);
  var onClick = useCallback(function () {
    if (editingLabel !== null || selection.length > 0 && selection[selection.length - 1].email.trim() === '') {
      return;
    }

    createNewLabel(selection);
  }, [selection, editingLabel]);
  var onInputFocus = useCallback(function (event) {
    if (editingLabel === null && event.target === inputRef.current) {
      createNewLabel(selection);
    }
  }, [selection, editingLabel]);
  var onInputBlur = useCallback(function (event) {
    var _ref$current;

    if (event.relatedTarget && (!((_ref$current = ref.current) !== null && _ref$current !== void 0 && _ref$current.contains(event.relatedTarget)) || event.relatedTarget === inputRef.current)) {
      setInternalWarning(false);
      setSelection(selection.filter(function (selection) {
        return selection.email.trim() !== '';
      }));
      setEditingLabel(null);
      onBlur && onBlur(event);
    }
  }, [selection, onBlur]);
  var onTagFocus = useCallback(function () {
    setSelection(selection.filter(function (selection) {
      return selection.email.trim() !== '';
    }));
    setEditingLabel(null);
  }, [selection, setSelection, setEditingLabel]);
  var onRemoveHandler = useCallback(function (index) {
    if (editingLabel !== index && selection[index].email !== '') {
      onUpdateLabel(index);
      return;
    }

    if (index > 0) {
      var newSelection = _toConsumableArray(selection);

      newSelection[index] = {
        email: ''
      };
      newSelection.splice(index - 1, 1);
      setSelection(newSelection);
      setEditingLabel(index - 1);
      changeHandler(newSelection);
    }
  }, [editingLabel, selection, onUpdateLabel, changeHandler]);
  var displayedWarning = warning !== null && warning !== void 0 ? warning : internalWarning;
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, _extends({
    ref: ref,
    className: cx(theme['label-input'], (_cx = {}, _defineProperty(_cx, theme['label-input--warning'], displayedWarning), _defineProperty(_cx, theme['label-input--error'], error), _defineProperty(_cx, theme['label-input--active'], editingLabel !== null), _cx)),
    onClick: onClick,
    onBlur: onInputBlur,
    onFocus: onFocus
  }, rest), selection === null || selection === void 0 ? void 0 : selection.map(function (option, i) {
    var _ref$current2;

    return /*#__PURE__*/React.createElement(Label, _extends({
      key: i,
      index: i,
      option: option,
      editing: editingLabel === i,
      invalid: option.valid === false,
      onClick: onLabelClick,
      onFinish: onUpdateLabel,
      onFocus: onTagFocus,
      onBlur: onBlurLabel,
      onRemove: onRemoveHandler,
      suggestions: validSuggestions,
      renderSuggestion: renderSuggestion,
      disableRemovalOfFirst: disableRemovalOfFirst
    }, menuFullWidth && {
      menuWidth: (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.offsetWidth
    }));
  }), (editingLabel === null || selection[editingLabel].email !== '') && /*#__PURE__*/React.createElement(Box, {
    className: theme['label-input-focuser'],
    element: "input",
    id: id,
    ref: inputRef,
    onFocus: onInputFocus
  })), /*#__PURE__*/React.createElement(ValidationText, {
    warning: displayedWarning,
    error: !displayedWarning && error
  }));
};

export default EmailSelector;