"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.type = type;
var _hostComponentNames = require("../../helpers/host-component-names");
var _eventBuilder = require("../event-builder");
var _errors = require("../../helpers/errors");
var _pointerEvents = require("../../helpers/pointer-events");
var _utils = require("../utils");
var _parseKeys = require("./parseKeys");
async function type(element, text, options) {
  if (!(0, _hostComponentNames.isHostTextInput)(element)) {
    throw new _errors.ErrorWithStack(`type() works only with host "TextInput" elements. Passed element has type "${element.type}".`, type);
  }

  // Skip events if the element is disabled
  if (element.props.editable === false || !(0, _pointerEvents.isPointerEventEnabled)(element)) {
    return;
  }
  const keys = (0, _parseKeys.parseKeys)(text);
  if (!options?.skipPress) {
    (0, _utils.dispatchEvent)(element, 'pressIn', _eventBuilder.EventBuilder.Common.touch());
  }
  (0, _utils.dispatchEvent)(element, 'focus', _eventBuilder.EventBuilder.Common.focus());
  if (!options?.skipPress) {
    await (0, _utils.wait)(this.config);
    (0, _utils.dispatchEvent)(element, 'pressOut', _eventBuilder.EventBuilder.Common.touch());
  }
  let currentText = element.props.value ?? element.props.defaultValue ?? '';
  for (const key of keys) {
    const previousText = element.props.value ?? currentText;
    currentText = applyKey(previousText, key);
    await (0, _utils.wait)(this.config);
    emitTypingEvents(element, key, currentText, previousText);
  }
  const finalText = element.props.value ?? currentText;
  await (0, _utils.wait)(this.config);
  if (options?.submitEditing) {
    (0, _utils.dispatchEvent)(element, 'submitEditing', _eventBuilder.EventBuilder.TextInput.submitEditing(finalText));
  }
  (0, _utils.dispatchEvent)(element, 'endEditing', _eventBuilder.EventBuilder.TextInput.endEditing(finalText));
  (0, _utils.dispatchEvent)(element, 'blur', _eventBuilder.EventBuilder.Common.blur());
}
async function emitTypingEvents(element, key, currentText, previousText) {
  const isMultiline = element.props.multiline === true;
  (0, _utils.dispatchEvent)(element, 'keyPress', _eventBuilder.EventBuilder.TextInput.keyPress(key));

  // According to the docs only multiline TextInput emits textInput event
  // @see: https://github.com/facebook/react-native/blob/42a2898617da1d7a98ef574a5b9e500681c8f738/packages/react-native/Libraries/Components/TextInput/TextInput.d.ts#L754
  if (isMultiline) {
    (0, _utils.dispatchEvent)(element, 'textInput', _eventBuilder.EventBuilder.TextInput.textInput(currentText, previousText));
  }
  (0, _utils.dispatchEvent)(element, 'change', _eventBuilder.EventBuilder.TextInput.change(currentText));
  (0, _utils.dispatchEvent)(element, 'changeText', currentText);
  const selectionRange = (0, _utils.getTextRange)(currentText);
  (0, _utils.dispatchEvent)(element, 'selectionChange', _eventBuilder.EventBuilder.TextInput.selectionChange(selectionRange));

  // According to the docs only multiline TextInput emits contentSizeChange event
  // @see: https://reactnative.dev/docs/textinput#oncontentsizechange
  if (isMultiline) {
    const contentSize = (0, _utils.getTextContentSize)(currentText);
    (0, _utils.dispatchEvent)(element, 'contentSizeChange', _eventBuilder.EventBuilder.TextInput.contentSizeChange(contentSize));
  }
}
function applyKey(text, key) {
  if (key === 'Enter') {
    return `${text}\n`;
  }
  if (key === 'Backspace') {
    return text.slice(0, -1);
  }
  return text + key;
}
//# sourceMappingURL=type.js.map