'use strict';

exports.__esModule = true;
exports.default = undefined;

var _class, _temp2;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactCharacterCounter = require('react-character-counter');

var _reactCharacterCounter2 = _interopRequireDefault(_reactCharacterCounter);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _is = require('is');

var _is2 = _interopRequireDefault(_is);

var _Paragraph = require('../../atoms/text/Paragraph');

var _Paragraph2 = _interopRequireDefault(_Paragraph);

require('./style.css');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

// These components exist to make it clear in FeedbackForm's render what's going on.
var RefererField = function RefererField(props) {
  return _react2.default.createElement('input', _extends({ type: 'hidden' }, props));
};
var NodeIdField = function NodeIdField(props) {
  return _react2.default.createElement('input', _extends({ type: 'hidden' }, props));
};
// Required for jsonp responses to work.
var JsonPField = function JsonPField() {
  return _react2.default.createElement('input', { type: 'hidden', name: 'jsonp', value: 1 });
};
// A hidden input field that prevents FormStack from looking for a required field that wasn't filled in.
var HiddenFields = function HiddenFields(props) {
  var formId = props.formId,
      rest = _objectWithoutProperties(props, ['formId']);

  return _react2.default.createElement('input', _extends({ type: 'hidden', name: 'hidden_fields', id: 'hidden_fields' + formId }, rest));
};
HiddenFields.propTypes = process.env.NODE_ENV !== "production" ? {
  /** The form id that the hidden input will be rendered within. */
  formId: _propTypes2.default.number
} : {};

var FeedbackForm = (_temp2 = _class = function (_Component) {
  _inherits(FeedbackForm, _Component);

  function FeedbackForm() {
    var _temp, _this, _ret;

    _classCallCheck(this, FeedbackForm);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = {
      yesText: '',
      noText: '',
      errorMessage: _react2.default.createElement(
        _Paragraph2.default,
        { className: 'error' },
        'Please go back and fill in any required fields (marked with an *)'
      ),
      feedbackChoice: null,
      hasError: [],
      success: false,
      formSubmitted: false
    }, _this.yesRadio = _react2.default.createRef(), _this.yesTextArea = _react2.default.createRef(), _this.noRadio = _react2.default.createRef(), _this.noTextArea = _react2.default.createRef(), _this.submitButton = _react2.default.createRef(), _this.defaultDisclaimer = function () {
      return _react2.default.createElement(
        'div',
        { id: 'feedback-note', className: 'ma__disclaimer' },
        'We use your feedback to help us improve this site but we are not able to respond directly. ',
        _react2.default.createElement(
          'strong',
          null,
          'Please do not include personal or contact information.'
        ),
        ' If you need a response, please locate the contact information elsewhere on this page or in the footer.'
      );
    }, _this.prefixLabel = function (id) {
      return 'label' + id;
    }, _this.prefixField = function (id) {
      return 'field' + id;
    }, _this.handleRadioChange = function (e) {
      if (e.currentTarget === _this.yesRadio.current) {
        return { feedbackChoice: true };
      }
      if (e.currentTarget === _this.noRadio.current) {
        return { feedbackChoice: false };
      }
      return {};
    }, _this.handleChange = function (e) {
      var newState = {};
      e.persist();
      if (e.currentTarget === _this.yesRadio.current || e.currentTarget === _this.noRadio.current) {
        newState = Object.assign(newState, _this.handleRadioChange(e));
      }
      if (e.currentTarget === _this.yesTextArea.current) {
        newState = Object.assign(newState, { yesText: e.currentTarget.value });
      }
      if (e.currentTarget === _this.noTextArea.current) {
        newState = Object.assign(newState, { noText: e.currentTarget.value });
      }
      // If the form was previously submitted but the user made a new change, reset the form submitted status.
      if (_this.state.formSubmitted && Object.keys(newState).length > 0) {
        newState.formSubmitted = false;
        newState.success = false;
        newState.successMessage = '';
      }
      _this.setState(newState, _this.checkForErrors);
    }, _this.removeError = function (errors, idToRemove) {
      return errors.filter(function (fieldId) {
        return !_is2.default.equal(fieldId, idToRemove);
      });
    }, _this.checkForErrors = function () {
      var hasError = [].concat(_this.state.hasError);
      var _this$props = _this.props,
          radioId = _this$props.radioId,
          noFeedbackId = _this$props.noFeedbackId;
      var _this$state = _this.state,
          feedbackChoice = _this$state.feedbackChoice,
          formSubmitted = _this$state.formSubmitted;
      // The user has not selected yes or no.

      if (!hasError.includes(radioId) && feedbackChoice === null) {
        hasError.push(radioId);
      }
      if (hasError.includes(radioId) && !_is2.default.nil(feedbackChoice)) {
        hasError = _this.removeError(hasError, radioId);
      }
      // The user has selected no but has not typed any feedback.
      if (!hasError.includes(noFeedbackId) && feedbackChoice === false && formSubmitted && _is2.default.empty(_this.noTextArea.current.value)) {
        hasError.push(noFeedbackId);
      } else if (hasError.includes(noFeedbackId) && feedbackChoice === false && !_is2.default.empty(_this.noTextArea.current.value)) {
        hasError = _this.removeError(hasError, noFeedbackId);
      }
      // If the user changed choices from no to yes, remove the error for no if there was one.
      if (feedbackChoice === true && hasError.includes(noFeedbackId)) {
        hasError = _this.removeError(hasError, noFeedbackId);
      }
      // Prevent calling setState too often while typing in textareas.
      if (!_is2.default.equal(hasError, _this.state.hasError)) {
        _this.setState({ hasError: hasError });
      }
      return hasError;
    }, _this.handleSubmit = function (e) {
      e.preventDefault();
      // Update the component state to know that the form was just submitted,
      // then check the form for any errors based on this new state.
      _this.setState({ formSubmitted: true }, function () {
        // checkForErrors doesn't immediately update state, so it returns what this.state.hasError is being set to.
        var errors = _this.checkForErrors();
        // If no remaining errors, submit form.
        // Since we have to use jsonp and this component could be used with server side rendering, ensure that window exists.
        if (window && _is2.default.array.empty(errors)) {
          Promise.resolve().then(function () {
            return _interopRequireWildcard(require('b-jsonp'));
          }).then(function (module) {
            var jsonp = module.default;
            var form = document.getElementById('fsForm' + _this.props.formId);
            var data = new FormData(form);
            var body = {};
            new Map(data.entries()).forEach(function (value, key) {
              body[key] = value;
            });
            // This library leaves behind the script added by formstack in the head of the document.
            // Any errors are handled by onSubmitError and the response is handled through onPostSubmit.
            // jsonp requires you to pass a function for the last param though.
            jsonp('https://www.formstack.com/forms/index.php', body, {
              prefix: 'form' + _this.props.formId,
              name: 'onPostSubmit'
            }, function () {});
          });
        }
      });
    }, _temp), _possibleConstructorReturn(_this, _ret);
  }

  FeedbackForm.prototype.componentDidMount = function componentDidMount() {
    var _this2 = this;

    if (window) {
      // We don't have the FormStack class available, but we can fake like we do:
      window['form' + this.props.formId] = {
        onSubmitError: function onSubmitError(err) {
          if (err) {
            var hasError = [].concat(_this2.state.hasError);
            hasError.push(_this2.props.radioId);
            hasError.push(_this2.props.noFeedbackId);
            var errorMessage = _react2.default.createElement(
              _Paragraph2.default,
              { className: 'error' },
              err.error
            );
            _this2.setState({ hasError: hasError, errorMessage: errorMessage });
          }
        },
        onPostSubmit: function onPostSubmit() {
          _this2.setState({ success: true });
        }
      };
    }
  };
  // Handles the onChange event for the yes/no radio buttons as well as the yes/no textareas.


  FeedbackForm.prototype.render = function render() {
    var _props = this.props,
        yesFeedbackId = _props.yesFeedbackId,
        yesDisclaimer = _props.yesDisclaimer,
        noFeedbackId = _props.noFeedbackId,
        noDisclaimer = _props.noDisclaimer,
        refererId = _props.refererId,
        formId = _props.formId,
        formRef = _props.formRef,
        radioId = _props.radioId,
        nodeId = _props.nodeId,
        successMessage = _props.successMessage;
    var _state = this.state,
        hasError = _state.hasError,
        success = _state.success,
        feedbackChoice = _state.feedbackChoice,
        formSubmitted = _state.formSubmitted,
        noText = _state.noText,
        yesText = _state.yesText,
        errorMessage = _state.errorMessage;

    var yesId = this.prefixField(yesFeedbackId);
    var noId = this.prefixField(noFeedbackId);
    var formProps = {
      id: 'fsForm' + formId,
      method: 'post',
      className: 'formForm',
      onSubmit: this.handleSubmit,
      action: 'https://www.formstack.com/forms/index.php',
      encType: 'multipart/form-data'
    };
    // Allows other components to have direct access to the form element.
    if (formRef) {
      formProps.ref = formRef;
    }
    var refererProps = {
      id: this.prefixField(refererId),
      name: this.prefixField(refererId),
      size: '50',
      value: window.location.href,
      className: 'fsField'
    };
    var yesFieldSetClassNames = (0, _classnames2.default)({
      'radio-yes': true,
      error: hasError.includes(yesFeedbackId)
    });
    var noFieldSetClassNames = (0, _classnames2.default)({
      'radio-no': true,
      error: hasError.includes(noFeedbackId)
    });
    var noTextAreaClassNames = (0, _classnames2.default)({
      'fsField required': true,
      error: hasError.includes(noFeedbackId)
    });
    var radiosClassNames = hasError.includes(radioId) ? 'error' : null;
    var messsageClassNames = (0, _classnames2.default)({
      messages: true,
      hide: success === false && _is2.default.array.empty(hasError)
    });
    var messageStyle = {
      fontWeight: 'bold'
    };
    if (!_is2.default.array.empty(hasError)) {
      messageStyle.color = 'red';
    }
    var characterCounterProps = {
      maxLength: 10000,
      wrapperStyle: {
        display: 'block',
        fontSize: '17px',
        lineHeight: '1.625rem',
        textAlign: 'right'
      },
      characterCounterStyle: {
        position: 'relative',
        display: 'block',
        bottom: '32px',
        right: '5px',
        top: 'auto',
        fontSize: '1rem',
        fontWeight: 400,
        lineHeight: '1.625rem'
      },
      overrideStyle: true
    };
    return success && formSubmitted ? _react2.default.createElement(
      'div',
      { className: 'ma__feedback-form', 'data-mass-feedback-form': true },
      _react2.default.createElement(
        'h2',
        { className: 'visually-hidden' },
        'Feedback'
      ),
      _react2.default.createElement(
        'form',
        _extends({ noValidate: true }, formProps),
        _react2.default.createElement(
          'fieldset',
          null,
          _react2.default.createElement(
            'div',
            { className: messsageClassNames, style: messageStyle },
            _is2.default.fn(successMessage) && successMessage()
          )
        )
      )
    ) : _react2.default.createElement(
      'div',
      { className: 'ma__feedback-form', 'data-mass-feedback-form': true },
      _react2.default.createElement(
        'h2',
        { className: 'visually-hidden' },
        'Feedback'
      ),
      _react2.default.createElement(
        'form',
        _extends({ noValidate: true }, formProps),
        _react2.default.createElement('input', { type: 'hidden', name: 'form', value: formId }),
        _react2.default.createElement(JsonPField, null),
        _react2.default.createElement('input', { type: 'hidden', name: 'viewkey', value: 'vx39GBYJhi' }),
        feedbackChoice === true && _react2.default.createElement(HiddenFields, { formId: formId, value: noId }),
        feedbackChoice === false && _react2.default.createElement(HiddenFields, { formId: formId, value: yesId }),
        _react2.default.createElement('input', { type: 'hidden', name: '_submit', value: '1' }),
        _react2.default.createElement('input', { type: 'hidden', name: 'style_version', value: '3' }),
        _react2.default.createElement('input', { type: 'hidden', id: 'viewparam', name: 'viewparam', value: '524744' }),
        _react2.default.createElement(RefererField, refererProps),
        _react2.default.createElement(NodeIdField, { id: 'field58154059', name: 'field58154059', value: nodeId }),
        _react2.default.createElement(NodeIdField, { id: 'field57432673', name: 'field57432673', value: nodeId }),
        _react2.default.createElement(
          'fieldset',
          { className: radiosClassNames },
          _react2.default.createElement(
            'legend',
            { className: 'fsLabel requiredLabel fsLabelVertical' },
            'Did you find what you were looking for on this webpage?',
            _react2.default.createElement(
              'span',
              null,
              ' * ',
              _react2.default.createElement(
                'span',
                { className: 'visually-hidden' },
                'required'
              )
            )
          ),
          _react2.default.createElement(
            'div',
            { className: 'ma__input-group__items ma__input-group__items--inline' },
            _react2.default.createElement(
              'div',
              { className: 'ma__input-group__item' },
              _react2.default.createElement(
                'span',
                { className: 'ma__input-radio' },
                _react2.default.createElement('input', { className: 'fsField required', id: this.prefixField(radioId) + '_1', onChange: this.handleChange, ref: this.yesRadio, name: this.prefixField(radioId), type: 'radio', value: 'Yes' }),
                _react2.default.createElement(
                  'label',
                  { className: 'fsOptionLabel ma__input-radio__label', htmlFor: this.prefixField(radioId) + '_1' },
                  'Yes'
                )
              )
            ),
            _react2.default.createElement(
              'div',
              { className: 'ma__input-group__item' },
              _react2.default.createElement(
                'span',
                { className: 'ma__input-radio' },
                _react2.default.createElement('input', { className: 'fsField required', id: this.prefixField(radioId) + '_2', onChange: this.handleChange, ref: this.noRadio, name: this.prefixField(radioId), type: 'radio', value: 'No' }),
                _react2.default.createElement(
                  'label',
                  { className: 'fsOptionLabel ma__input-radio__label', htmlFor: this.prefixField(radioId) + '_2' },
                  'No'
                )
              )
            )
          )
        ),
        feedbackChoice === false && _react2.default.createElement(
          'fieldset',
          { className: noFieldSetClassNames },
          _react2.default.createElement(
            'label',
            { htmlFor: noId },
            'If "No," please tell us what you were looking for:',
            _react2.default.createElement(
              'span',
              null,
              ' * ',
              _react2.default.createElement(
                'span',
                { className: 'visually-hidden' },
                'required'
              )
            )
          ),
          _react2.default.createElement(
            'div',
            { className: 'ma__textarea__wrapper' },
            _react2.default.createElement(
              _reactCharacterCounter2.default,
              _extends({ value: noText }, characterCounterProps),
              _react2.default.createElement('textarea', {
                id: noId,
                ref: this.noTextArea,
                onChange: this.handleChange,
                className: noTextAreaClassNames,
                name: noId,
                'aria-required': 'true',
                maxLength: '10000',
                disabled: feedbackChoice === false ? null : 'disabled',
                'aria-describedby': 'feedback-note'
              })
            )
          ),
          _react2.default.createElement('input', { type: 'hidden', id: yesId, name: yesId, value: '' }),
          _is2.default.fn(noDisclaimer) ? noDisclaimer() : this.defaultDisclaimer()
        ),
        feedbackChoice === true && _react2.default.createElement(
          'fieldset',
          { className: yesFieldSetClassNames },
          _react2.default.createElement(
            'label',
            { htmlFor: yesId },
            'Is there anything else you would like to tell us?'
          ),
          _react2.default.createElement(
            'div',
            { className: 'ma__textarea__wrapper' },
            _react2.default.createElement(
              _reactCharacterCounter2.default,
              _extends({ value: yesText }, characterCounterProps),
              _react2.default.createElement('textarea', {
                ref: this.yesTextArea,
                onChange: this.handleChange,
                id: yesId,
                name: yesId,
                maxLength: '10000',
                disabled: feedbackChoice === true ? null : 'disabled',
                'aria-describedby': 'feedback-note2'
              })
            )
          ),
          _react2.default.createElement('input', { type: 'hidden', id: noId, name: noId, value: '' }),
          _is2.default.fn(yesDisclaimer) ? yesDisclaimer() : this.defaultDisclaimer()
        ),
        _react2.default.createElement(
          'fieldset',
          { className: 'ma_feedback-fieldset ma__mass-feedback-form__form--submit-wrapper' },
          _react2.default.createElement(
            'div',
            { className: messsageClassNames, style: messageStyle },
            success === false && errorMessage
          ),
          _react2.default.createElement('input', {
            id: 'submitButton2521317',
            ref: this.submitButton,
            className: 'submitButton ma__button ma__button--small',
            style: { display: 'block' },
            type: 'submit',
            value: 'Send Feedback'
          })
        )
      )
    );
  };

  return FeedbackForm;
}(_react.Component), _class.defaultProps = {
  formId: 2521317,
  radioId: 47054416,
  yesFeedbackId: 52940022,
  noFeedbackId: 47054414,
  refererId: 47056299
}, _temp2);
exports.default = FeedbackForm;
FeedbackForm.propTypes = process.env.NODE_ENV !== "production" ? {
  /** A ref object as created by React.createRef(). Will be applied to the form element. */
  formRef: _propTypes2.default.oneOfType([_propTypes2.default.func, _propTypes2.default.shape({ current: _propTypes2.default.any })]),
  /** A function whose return value is displayed after a successful form submission. */
  successMessage: _propTypes2.default.func.isRequired,
  /** The field id number for the yes textarea. */
  yesFeedbackId: _propTypes2.default.number,
  /** The field id number for the no textarea. */
  noFeedbackId: _propTypes2.default.number,
  /** The field id number for the referer. */
  refererId: _propTypes2.default.number,
  /** The id number for the form from FormStack. */
  formId: _propTypes2.default.number,
  /** The field id number for the yes/no radio buttons. */
  radioId: _propTypes2.default.number,
  /** A drupal node id number for the referer. */
  nodeId: _propTypes2.default.number,
  /** A function whose return value is rendered under the yes textarea. */
  yesDisclaimer: _propTypes2.default.func,
  /** A function whose return value is rendered under the no textarea. */
  noDisclaimer: _propTypes2.default.func
} : {};
module.exports = exports['default'];