import _extends from "@babel/runtime/helpers/esm/extends";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["mapPropsToValues"],
  _excluded2 = ["children"];
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
/* eslint-disable @typescript-eslint/ban-types */
import hoistNonReactStatics from 'hoist-non-react-statics';
import * as React from 'react';
import { FormWrapper } from './FormWrapper';
import { isFunction } from './utils';

/**
 * State, handlers, and helpers injected as props into the wrapped form component.
 * Used with withFormik()
 *
 * @deprecated  Use `OuterProps & FormikProps<Values>` instead.
 */

/**
 * Formik helpers + { props }
 */

/**
 * withFormik() configuration options. Backwards compatible.
 */

/**
 * A public higher-order component to access the imperative API
 */
export default function withFormik(_ref) {
  var _ref$mapPropsToValues = _ref.mapPropsToValues,
    mapPropsToValues = _ref$mapPropsToValues === void 0 ? function (vanillaProps) {
      var val = {};
      for (var k in vanillaProps) {
        if (vanillaProps.hasOwnProperty(k) && typeof vanillaProps[k] !== 'function') {
          // @todo TypeScript fix
          val[k] = vanillaProps[k];
        }
      }
      return val;
    } : _ref$mapPropsToValues,
    config = _objectWithoutProperties(_ref, _excluded);
  return function createFormik(Component) {
    var componentDisplayName = Component.displayName || Component.name || Component.constructor && Component.constructor.name || 'Component';
    /**
     * We need to use closures here for to provide the wrapped component's props to
     * the respective withFormik config methods.
     */
    var C = /*#__PURE__*/function (_React$Component) {
      function C() {
        var _this;
        _classCallCheck(this, C);
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }
        _this = _callSuper(this, C, [].concat(args));
        _defineProperty(_this, "validate", function (values) {
          return config.validate(values, _this.props);
        });
        _defineProperty(_this, "validationSchema", function () {
          return isFunction(config.validationSchema) ? config.validationSchema(_this.props) : config.validationSchema;
        });
        _defineProperty(_this, "handleSubmit", function (values, actions) {
          return config.handleSubmit(values, _extends({}, actions, {
            props: _this.props
          }));
        });
        /**
         * Just avoiding a render callback for perf here
         */
        _defineProperty(_this, "renderFormComponent", function (formikProps) {
          return /*#__PURE__*/React.createElement(Component, _extends({}, _this.props, formikProps));
        });
        return _this;
      }
      _inherits(C, _React$Component);
      return _createClass(C, [{
        key: "render",
        value: function render() {
          var _ref2 = this.props,
            children = _ref2.children,
            props = _objectWithoutProperties(_ref2, _excluded2);
          return /*#__PURE__*/React.createElement(FormWrapper, _extends({}, props, config, {
            validate: config.validate && this.validate,
            validationSchema: config.validationSchema && this.validationSchema,
            initialValues: mapPropsToValues(this.props),
            initialStatus: config.mapPropsToStatus && config.mapPropsToStatus(this.props),
            initialErrors: config.mapPropsToErrors && config.mapPropsToErrors(this.props),
            initialTouched: config.mapPropsToTouched && config.mapPropsToTouched(this.props),
            onSubmit: this.handleSubmit,
            children: this.renderFormComponent
          }));
        }
      }]);
    }(React.Component);
    _defineProperty(C, "displayName", "WithFormik(".concat(componentDisplayName, ")"));
    return hoistNonReactStatics(C, Component // cast type to ComponentClass (even if SFC)
    );
  };
}