'use strict';

var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var React = require('react');
var formik = require('formik');
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var ramda = require('ramda');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var neetoCist = require('@bigbinary/neeto-cist');
var jsxRuntime = require('react/jsx-runtime');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
var _asyncToGenerator__default = /*#__PURE__*/_interopDefault(_asyncToGenerator);
var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
var _toConsumableArray__default = /*#__PURE__*/_interopDefault(_toConsumableArray);
var _slicedToArray__default = /*#__PURE__*/_interopDefault(_slicedToArray);

var _transformObjectToDotNotation = function transformObjectToDotNotation(object) {
  var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  var result = [];
  Object.entries(object).forEach(function (_ref) {
    var _ref2 = _slicedToArray__default.default(_ref, 2),
      key = _ref2[0],
      value = _ref2[1];
    if (!value) return;
    var nextKey = prefix ? "".concat(prefix, ".").concat(key) : key;
    if (ramda.is(Object, value)) {
      result.push.apply(result, _toConsumableArray__default.default(_transformObjectToDotNotation(value, nextKey)));
    } else {
      result.push(nextKey);
    }
  });
  return result;
};
var getErrorFieldName = function getErrorFieldName(formikErrors) {
  var _transformObjectToDot;
  return (_transformObjectToDot = _transformObjectToDotNotation(formikErrors)) === null || _transformObjectToDot === void 0 ? void 0 : _transformObjectToDot[0];
};
var getFieldsWithServerError = function getFieldsWithServerError() {
  var status = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  return Object.keys(status).filter(function (fieldName) {
    return neetoCist.isPresent(status[fieldName]);
  });
};
var scrollToError = function scrollToError(formRef, errors, status) {
  var fieldErrorName = getErrorFieldName(errors);
  var _getFieldsWithServerE = getFieldsWithServerError(status),
    _getFieldsWithServerE2 = _slicedToArray__default.default(_getFieldsWithServerE, 1),
    fieldWithServerError = _getFieldsWithServerE2[0];
  if (!fieldErrorName && !fieldWithServerError) return;
  var errorFieldName = fieldErrorName || fieldWithServerError;
  var errorFormElement = formRef.current.querySelector("[name=\"".concat(errorFieldName, "\"]"));
  errorFormElement === null || errorFormElement === void 0 ? void 0 : errorFormElement.scrollIntoView({
    behavior: "smooth",
    block: "center"
  });
};

var ScrollToErrorField = function ScrollToErrorField(_ref) {
  var formRef = _ref.formRef;
  var _useFormikContext = formik.useFormikContext(),
    submitCount = _useFormikContext.submitCount,
    isValid = _useFormikContext.isValid,
    errors = _useFormikContext.errors,
    status = _useFormikContext.status;
  React.useEffect(function () {
    var fieldsWithServerError = getFieldsWithServerError(status);
    if (!formRef.current || isValid && ramda.isEmpty(fieldsWithServerError)) {
      return;
    }
    scrollToError(formRef, errors, status);
  }, [submitCount]);
  return null;
};

var _excluded = ["validateForm", "setErrors", "setTouched", "submitForm"];
function ownKeys$1(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$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), true).forEach(function (r) { _defineProperty__default.default(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var FormWrapper = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
  var className = _ref.className,
    formProps = _ref.formProps,
    children = _ref.children,
    scrollToErrorField = _ref.scrollToErrorField;
  var _useFormikContext = formik.useFormikContext(),
    validateForm = _useFormikContext.validateForm,
    setErrors = _useFormikContext.setErrors,
    setTouched = _useFormikContext.setTouched,
    submitForm = _useFormikContext.submitForm,
    formikBag = _objectWithoutProperties__default.default(_useFormikContext, _excluded);
  var isFormDirty = formikBag.dirty,
    isSubmitting = formikBag.isSubmitting,
    status = formikBag.status;
  var formRefForScrollToErrorField = React.useRef();
  var formRef = ref || formRefForScrollToErrorField;
  var handleKeyDown = React.useCallback(/*#__PURE__*/function () {
    var _ref2 = _asyncToGenerator__default.default(/*#__PURE__*/_regeneratorRuntime__default.default.mark(function _callee(event) {
      var isEventFromEditorOrTextarea, errors, fieldStatuses, _t;
      return _regeneratorRuntime__default.default.wrap(function (_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            isEventFromEditorOrTextarea = event.target.tagName === "TEXTAREA" || event.target.editor;
            if (!(event.key !== "Enter")) {
              _context.next = 1;
              break;
            }
            return _context.abrupt("return");
          case 1:
            if (!(isEventFromEditorOrTextarea && !event.metaKey)) {
              _context.next = 2;
              break;
            }
            return _context.abrupt("return");
          case 2:
            event.preventDefault();
            if (!event.shiftKey) {
              _context.next = 3;
              break;
            }
            return _context.abrupt("return");
          case 3:
            if (!(!isFormDirty || isSubmitting)) {
              _context.next = 4;
              break;
            }
            return _context.abrupt("return");
          case 4:
            _context.prev = 4;
            _context.next = 5;
            return validateForm();
          case 5:
            errors = _context.sent;
            fieldStatuses = getFieldsWithServerError(status);
            if (Object.keys(errors).length > 0 || Object.keys(fieldStatuses).length > 0) {
              setErrors(errors);
              setTouched(_objectSpread$1(_objectSpread$1({}, errors), status));
              scrollToErrorField && scrollToError(formRef, errors, status);
            } else {
              submitForm();
            }
            _context.next = 7;
            break;
          case 6:
            _context.prev = 6;
            _t = _context["catch"](4);
            // eslint-disable-next-line no-console
            console.error("An unhandled error was caught from validateForm()", _t);
          case 7:
          case "end":
            return _context.stop();
        }
      }, _callee, null, [[4, 6]]);
    }));
    return function (_x) {
      return _ref2.apply(this, arguments);
    };
  }(), [validateForm, setErrors, setTouched, isFormDirty, isSubmitting, submitForm, status]);
  return /*#__PURE__*/jsxRuntime.jsxs(formik.Form, _objectSpread$1(_objectSpread$1({
    className: className,
    noValidate: true,
    "data-testid": "neeto-ui-form-wrapper",
    ref: formRef,
    onKeyDown: handleKeyDown
  }, formProps), {}, {
    children: [scrollToErrorField && /*#__PURE__*/jsxRuntime.jsx(ScrollToErrorField, {
      formRef: formRef
    }), children]
  }));
});
FormWrapper.displayName = "FormWrapper";

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), true).forEach(function (r) { _defineProperty__default.default(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 Form = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
  var className = _ref.className,
    _children = _ref.children,
    formikProps = _ref.formikProps,
    formProps = _ref.formProps,
    _ref$scrollToErrorFie = _ref.scrollToErrorField,
    scrollToErrorField = _ref$scrollToErrorFie === void 0 ? false : _ref$scrollToErrorFie;
  var formikRef = React.useRef();
  var handleSubmit = function handleSubmit(values, actions) {
    var _formikRef$current;
    var fieldsWithServerError = getFieldsWithServerError((_formikRef$current = formikRef.current) === null || _formikRef$current === void 0 ? void 0 : _formikRef$current.status);
    if (fieldsWithServerError.length > 0) {
      actions.setSubmitting(false);
      return undefined;
    }
    return formikProps.onSubmit(values, actions);
  };
  return /*#__PURE__*/jsxRuntime.jsx(formik.Formik, _objectSpread(_objectSpread({
    innerRef: formikRef
  }, formikProps), {}, {
    onSubmit: handleSubmit,
    children: function children(props) {
      return /*#__PURE__*/jsxRuntime.jsx(FormWrapper, {
        className: className,
        formProps: formProps,
        ref: ref,
        scrollToErrorField: scrollToErrorField,
        children: typeof _children === "function" ? _children(props) : _children
      });
    }
  }));
});
Form.displayName = "Form";

module.exports = Form;
//# sourceMappingURL=Form.js.map
