import { _ as _extends } from '../extends-C4cduGrv.js';
import { _ as _defineProperty } from '../defineProperty-CEd-kZQW.js';
import { _ as _slicedToArray } from '../slicedToArray-BB-AwwkK.js';
import React__default, { useState, useRef } from 'react';
import PropTypes from 'prop-types';

var noop = function noop() {};
/**
 * This component was originally developed to support an input for an MFA token.
 *
 * Go ahead and evolve this component per your needs - I'm sure we'll learn more about how this should behave.
 *
 * If we discover that this approach isn't really working, Joseph has also suggested a different approach for us to try.
 * [Check it out](https://codesandbox.io/s/old-wood-rqwij6?file=/src/MultiBox.js)
 */


var MultiBoxInput = function MultiBoxInput(_ref) {
  var name = _ref.name,
      numberOfCells = _ref.numberOfCells,
      _ref$inputAttrs = _ref.inputAttrs,
      inputAttrs = _ref$inputAttrs === void 0 ? {} : _ref$inputAttrs,
      _ref$cellClasses = _ref.cellClasses,
      cellClasses = _ref$cellClasses === void 0 ? "" : _ref$cellClasses,
      _ref$containerClasses = _ref.containerClasses,
      containerClasses = _ref$containerClasses === void 0 ? "" : _ref$containerClasses,
      _ref$onChange = _ref.onChange,
      onChange = _ref$onChange === void 0 ? noop : _ref$onChange,
      initialValue = _ref.value;

  var _useState = useState(Array.from(initialValue || "")),
      _useState2 = _slicedToArray(_useState, 2),
      value = _useState2[0],
      setValue = _useState2[1];

  var inputContainerRef = useRef(null);

  var handlePaste = function handlePaste(event) {
    var text = event.clipboardData.getData('text'); // truncate the pasted value to the number of cells available

    var newValue = Array.from(text).slice(0, numberOfCells);
    setValue(newValue); // move the cursor to the last cell

    focusInput(newValue.length - 1);
    onChange({
      value: newValue.join("")
    });
  };

  var updateCell = function updateCell(index, event) {
    var newValue = Object.assign([], value, _defineProperty({}, index, event.target.value));
    setValue(newValue); // if cell was filled, and there is a next cell,
    // move to next cell

    if (newValue[index] !== "" && index < numberOfCells - 1) {
      focusInput(index + 1);
    } // call parent hook


    onChange({
      value: newValue.join("")
    });
  };

  var handleKeyStroke = function handleKeyStroke(index, event) {
    if (event.ctrlKey || event.metaKey) {
      switch (event.key) {
        case "a":
          selectAll(event);
          break;

        case "c":
          copyAll(event);
          break;

        case "x":
          cutAll(event);
          break;

        case "Backspace" :
          deleteAll(event);
          break;
      }
    }

    if (event.key === "Backspace" || event.key === "Delete") {
      var selection = window.getSelection();
      var inputContainerNode = inputContainerRef.current;
      var inputs = Array.from(inputContainerNode.querySelectorAll('input'));
      var allSelected = inputs.every(function (input) {
        return selection.containsNode(input);
      });

      if (allSelected) {
        deleteAll(event);
      } else {
        moveToPreviousCell(index);
      }
    }
  }; // If the current cell is empty, there is a previous cell,
  // move focus to the previous cell


  var moveToPreviousCell = function moveToPreviousCell(index) {
    if (value[index] !== "" && value[index] !== undefined) return;
    focusInput(index - 1);
  };

  var selectAll = function selectAll(event) {
    event.preventDefault();
    event.stopPropagation();
    var selection = window.getSelection();
    var inputContainerNode = inputContainerRef.current;
    selection.selectAllChildren(inputContainerNode);
  };

  var copyAll = function copyAll(event) {
    event.preventDefault();
    event.stopPropagation();
    var input = value.join("");
    navigator.clipboard.writeText(input);
  };

  var cutAll = function cutAll(event) {
    event.preventDefault();
    event.stopPropagation();
    var input = value.join("");
    navigator.clipboard.writeText(input);
    setValue(Array.from({
      length: numberOfCells
    }));
    focusInput(0);
  };

  var deleteAll = function deleteAll(event) {
    event.preventDefault();
    event.stopPropagation();
    setValue(Array.from({
      length: numberOfCells
    }));
    focusInput(0);
  };

  var focusInput = function focusInput(index) {
    var inputContainerNode = inputContainerRef.current;
    var input = inputContainerNode.querySelectorAll('input')[index];
    if (!input) return;
    input.focus();
  };

  var cellClassNames = "outline-none border border-gray-200 focus:border-blue-500 leading-10 px-2 md:px-4 rounded mr-1 text-4xl w-full ".concat(cellClasses);
  return /*#__PURE__*/React__default.createElement("div", {
    "aria-label": name,
    className: "flex flex-row ".concat(containerClasses),
    ref: inputContainerRef
  }, Array.from({
    length: numberOfCells
  }).map(function (_, index) {
    return /*#__PURE__*/React__default.createElement("input", _extends({
      style: {
        maxWidth: 64,
        height: 80
      },
      autoFocus: index == 0 ? true : false,
      key: "multibox-cell-".concat(index),
      maxLength: 1,
      className: cellClassNames,
      value: value[index] || "",
      onKeyDown: function onKeyDown(e) {
        return handleKeyStroke(index, e);
      },
      onChange: function onChange(e) {
        return updateCell(index, e);
      },
      onPaste: handlePaste,
      inputMode: "numeric",
      autoComplete: "one-time-code",
      "aria-required": true
    }, inputAttrs));
  }));
};

MultiBoxInput.propTypes = {
  /** Name that will be applied to the component, used in a11y tools. */
  name: PropTypes.string.isRequired,

  /** How many cells should the input comprise. */
  numberOfCells: PropTypes.number.isRequired,

  /** HTML attributes that will be applied to each individual input cell */
  inputAttrs: PropTypes.object,

  /** CSS classNames that will be applied to each individual cell */
  cellClasses: PropTypes.string,

  /** CSS classNames that will be applied to the container that wraps the cells */
  containerClasses: PropTypes.string,

  /** Function that will be called when the input's value changes. The argument passed is the component's value as a string. */
  onChange: PropTypes.func,

  /** Value as a string. It will be split into an array of chars */
  value: PropTypes.string
};

export { MultiBoxInput as default };
