import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import React, { useState, useEffect, useContext } from 'react';
import { createClient, getDefaultClient } from '@formspree/core';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import _typeof from '@babel/runtime/helpers/typeof';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';

var FormspreeContext = React.createContext({
  client: undefined
});
FormspreeContext.displayName = 'Formspree';
var FormspreeProvider = function FormspreeProvider(props) {
  if (!props.project) {
    throw new Error('project is required');
  }

  var _useState = useState(function () {
    return createClient({
      project: props.project
    });
  }),
      _useState2 = _slicedToArray(_useState, 1),
      client = _useState2[0];

  useEffect(function () {
    client.startBrowserSession();
    return function () {
      client.teardown();
    };
  }, []);
  return React.createElement(FormspreeContext.Provider, {
    value: {
      client: client
    }
  }, props.children);
};
function useFormspree() {
  var _useContext = useContext(FormspreeContext),
      client = _useContext.client;

  return client || getDefaultClient();
}

var version = "2.2.5";

function isEvent(data) {
  return data.preventDefault !== undefined;
}

function useForm(formKey) {
  var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      submitting = _useState2[0],
      setSubmitting = _useState2[1];

  var _useState3 = useState(false),
      _useState4 = _slicedToArray(_useState3, 2),
      succeeded = _useState4[0],
      setSucceeded = _useState4[1];

  var _useState5 = useState([]),
      _useState6 = _slicedToArray(_useState5, 2),
      errors = _useState6[0],
      setErrors = _useState6[1];

  var globalClient = useFormspree();
  var client = args.client || globalClient;

  if (!client) {
    throw new Error('You must provide a Formspree client');
  }

  if (!formKey) {
    throw new Error('You must provide a form key or hashid ' + '(e.g. useForm("myForm") or useForm("123xyz")');
  }

  var debug = !!args.debug;
  var extraData = args.data;

  var reset = function reset() {
    setSubmitting(false);
    setSucceeded(false);
    setErrors([]);
  };

  var handleSubmit =
  /*#__PURE__*/
  function () {
    var _ref = _asyncToGenerator(
    /*#__PURE__*/
    _regeneratorRuntime.mark(function _callee(submissionData) {
      var getFormData, formData, appendExtraData, prop, extraDataValue;
      return _regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              getFormData = function getFormData(event) {
                event.preventDefault();
                var form = event.target;

                if (form.tagName != 'FORM') {
                  throw new Error('submit was triggered for a non-form element');
                }

                return new FormData(form);
              };

              formData = isEvent(submissionData) ? getFormData(submissionData) : submissionData;

              appendExtraData = function appendExtraData(prop, value) {
                if (formData instanceof FormData) {
                  formData.append(prop, value);
                } else {
                  formData = Object.assign(formData, _defineProperty({}, prop, value));
                }
              }; // Append extra data from config


              if (!(_typeof(extraData) === 'object')) {
                _context.next = 19;
                break;
              }

              _context.t0 = _regeneratorRuntime.keys(extraData);

            case 5:
              if ((_context.t1 = _context.t0()).done) {
                _context.next = 19;
                break;
              }

              prop = _context.t1.value;

              if (!(typeof extraData[prop] === 'function')) {
                _context.next = 16;
                break;
              }

              extraDataValue = extraData[prop].call(null);

              if (!(extraDataValue instanceof Promise)) {
                _context.next = 13;
                break;
              }

              _context.next = 12;
              return extraDataValue;

            case 12:
              extraDataValue = _context.sent;

            case 13:
              if (extraDataValue !== undefined) {
                appendExtraData(prop, extraDataValue);
              }

              _context.next = 17;
              break;

            case 16:
              appendExtraData(prop, extraData[prop]);

            case 17:
              _context.next = 5;
              break;

            case 19:
              setSubmitting(true);
              return _context.abrupt("return", client.submitForm(formKey, formData, {
                endpoint: args.endpoint,
                clientName: "@formspree/react@".concat(version)
              }).then(function (result) {
                var status = result.response.status;
                var body;

                if (status === 200) {
                  if (debug) console.log('Form submitted', result);
                  setSucceeded(true);
                  setErrors([]);
                } else if (status >= 400 && status < 500) {
                  body = result.body;
                  if (body.errors) setErrors(body.errors);
                  if (debug) console.log('Validation error', result);
                  setSucceeded(false);
                } else {
                  if (debug) console.log('Unexpected error', result);
                  setSucceeded(false);
                }

                return result;
              })["catch"](function (error) {
                if (debug) console.log('Unexpected error', error);
                setSucceeded(false);
                throw error;
              })["finally"](function () {
                setSubmitting(false);
              }));

            case 21:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    return function handleSubmit(_x) {
      return _ref.apply(this, arguments);
    };
  }();

  return [{
    submitting: submitting,
    succeeded: succeeded,
    errors: errors
  }, handleSubmit, reset];
}

var ValidationError = function ValidationError(props) {
  var prefix = props.prefix,
      field = props.field,
      errors = props.errors,
      attrs = _objectWithoutProperties(props, ["prefix", "field", "errors"]);

  var error = (errors || []).find(function (error) {
    return error.field == field;
  });

  if (!error) {
    return null;
  }

  return React.createElement("div", attrs, prefix, " ", error.message);
};

export { FormspreeProvider, ValidationError, useForm, useFormspree };
