import _extends from "@babel/runtime/helpers/esm/extends";
import _readOnlyError from "@babel/runtime/helpers/esm/readOnlyError";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
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";
var _excluded = ["validate", "name", "render", "as", "children", "component", "shouldUpdate", "formik"],
  _excluded2 = ["validate", "validationSchema"],
  _excluded3 = ["innerRef"],
  _excluded4 = ["innerRef"];
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; })(); }
import * as React from 'react';
import invariant from 'tiny-warning';
import { getIn, isEmptyChildren, isFunction } from './utils';
import connect from './connect';
/**
 * Custom Field component for quickly hooking into Formik
 * context and wiring up forms.
 */
var FastFieldInner = /*#__PURE__*/function (_React$Component) {
  function FastFieldInner(props) {
    var _this;
    _classCallCheck(this, FastFieldInner);
    _this = _callSuper(this, FastFieldInner, [props]);
    var render = props.render,
      children = props.children,
      component = props.component,
      is = props.as,
      name = props.name;
    invariant(!render, "<FastField render> has been deprecated. Please use a child callback function instead: <FastField name={".concat(name, "}>{props => ...}</FastField> instead."));
    invariant(!(component && render), 'You should not use <FastField component> and <FastField render> in the same <FastField> component; <FastField component> will be ignored');
    invariant(!(is && children && isFunction(children)), 'You should not use <FastField as> and <FastField children> as a function in the same <FastField> component; <FastField as> will be ignored.');
    invariant(!(component && children && isFunction(children)), 'You should not use <FastField component> and <FastField children> as a function in the same <FastField> component; <FastField component> will be ignored.');
    invariant(!(render && children && !isEmptyChildren(children)), 'You should not use <FastField render> and <FastField children> in the same <FastField> component; <FastField children> will be ignored');
    return _this;
  }
  _inherits(FastFieldInner, _React$Component);
  return _createClass(FastFieldInner, [{
    key: "shouldComponentUpdate",
    value: function shouldComponentUpdate(props) {
      if (this.props.shouldUpdate) {
        return this.props.shouldUpdate(props, this.props);
      } else if (props.name !== this.props.name || getIn(props.formik.values, this.props.name) !== getIn(this.props.formik.values, this.props.name) || getIn(props.formik.errors, this.props.name) !== getIn(this.props.formik.errors, this.props.name) || getIn(props.formik.touched, this.props.name) !== getIn(this.props.formik.touched, this.props.name) || Object.keys(this.props).length !== Object.keys(props).length || props.formik.isSubmitting !== this.props.formik.isSubmitting) {
        return true;
      } else {
        return false;
      }
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      // Register the Field with the parent Formik. Parent will cycle through
      // registered Field's validate fns right prior to submit
      this.props.formik.registerField(this.props.name, {
        validate: this.props.validate
      });
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      if (this.props.name !== prevProps.name) {
        this.props.formik.unregisterField(prevProps.name);
        this.props.formik.registerField(this.props.name, {
          validate: this.props.validate
        });
      }
      if (this.props.validate !== prevProps.validate) {
        this.props.formik.registerField(this.props.name, {
          validate: this.props.validate
        });
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.props.formik.unregisterField(this.props.name);
    }
  }, {
    key: "render",
    value: function render() {
      var _ref = this.props,
        validate = _ref.validate,
        name = _ref.name,
        render = _ref.render,
        is = _ref.as,
        children = _ref.children,
        component = _ref.component,
        shouldUpdate = _ref.shouldUpdate,
        formik = _ref.formik,
        props = _objectWithoutProperties(_ref, _excluded);
      var _validate = formik.validate,
        _validationSchema = formik.validationSchema,
        restOfFormik = _objectWithoutProperties(formik, _excluded2);
      var field = formik.getFieldProps(_extends({
        name: name
      }, props));
      var meta = {
        value: getIn(formik.values, name),
        error: getIn(formik.errors, name),
        touched: !!getIn(formik.touched, name),
        initialValue: getIn(formik.initialValues, name),
        initialTouched: !!getIn(formik.initialTouched, name),
        initialError: getIn(formik.initialErrors, name)
      };
      var bag = {
        field: field,
        meta: meta,
        form: restOfFormik
      };
      if (render) {
        return render(bag);
      }
      if (isFunction(children)) {
        return children(bag);
      }
      if (component) {
        // This behavior is backwards compat with earlier Formik 0.9 to 1.x
        if (typeof component === 'string') {
          var innerRef = props.innerRef,
            rest = _objectWithoutProperties(props, _excluded3);
          return /*#__PURE__*/React.createElement(component, _extends({
            ref: innerRef
          }, field, rest), children);
        }
        // We don't pass `meta` for backwards compat
        return /*#__PURE__*/React.createElement(component, _extends({
          field: field,
          form: formik
        }, props), children);
      }

      // default to input here so we can check for both `as` and `children` above
      var asElement = is || 'input';
      if (typeof asElement === 'string') {
        var _innerRef = props.innerRef,
          _rest = _objectWithoutProperties(props, _excluded4);
        return /*#__PURE__*/React.createElement(asElement, _extends({
          ref: _innerRef
        }, field, _rest), children);
      }
      return /*#__PURE__*/React.createElement(asElement, _extends({}, field, props), children);
    }
  }]);
}(React.Component);
export var FastField = connect(FastFieldInner);