"use strict";

Object.defineProperty(exports, "__esModule", {
	value: true
});

var _extends2 = require("babel-runtime/helpers/extends");

var _extends3 = _interopRequireDefault(_extends2);

var _objectWithoutProperties2 = require("babel-runtime/helpers/objectWithoutProperties");

var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);

var _regenerator = require("babel-runtime/regenerator");

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require("babel-runtime/helpers/createClass");

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn");

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require("babel-runtime/helpers/inherits");

var _inherits3 = _interopRequireDefault(_inherits2);

var _react = require("react");

var _react2 = _interopRequireDefault(_react);

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

exports.default = function (fn) {
	var refName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "wrap";
	var Loading = arguments[2];
	var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};

	var AsyncComponent = function (_Component) {
		(0, _inherits3.default)(AsyncComponent, _Component);

		function AsyncComponent() {
			var _ref;

			(0, _classCallCheck3.default)(this, AsyncComponent);

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

			var _this = (0, _possibleConstructorReturn3.default)(this, (_ref = AsyncComponent.__proto__ || Object.getPrototypeOf(AsyncComponent)).call.apply(_ref, [this].concat(params)));

			_this.state = {
				WrapComponent: null
			};
			return _this;
		}

		(0, _createClass3.default)(AsyncComponent, [{
			key: "componentDidMount",
			value: function () {
				var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
					var onBefore, onAfter, _ref3, WrapComponent;

					return _regenerator2.default.wrap(function _callee$(_context) {
						while (1) {
							switch (_context.prev = _context.next) {
								case 0:
									_context.prev = 0;
									onBefore = opts.onBefore, onAfter = opts.onAfter;

									onBefore = onBefore || this.props.onBefore;
									onAfter = onAfter || this.props.onAfter;

									// before
									onBefore && onBefore();

									// loading
									_context.next = 7;
									return fn();

								case 7:
									_ref3 = _context.sent;
									WrapComponent = _ref3.default;


									// after
									onAfter && onAfter();

									this.setState({
										WrapComponent: WrapComponent
									});
									_context.next = 16;
									break;

								case 13:
									_context.prev = 13;
									_context.t0 = _context["catch"](0);

									console.log(_context.t0);

								case 16:
								case "end":
									return _context.stop();
							}
						}
					}, _callee, this, [[0, 13]]);
				}));

				function componentDidMount() {
					return _ref2.apply(this, arguments);
				}

				return componentDidMount;
			}()
		}, {
			key: "render",
			value: function render() {
				var WrapComponent = this.state.WrapComponent;
				var _props = this.props,
				    onBefore = _props.onBefore,
				    onAfter = _props.onAfter,
				    onLoaded = _props.onLoaded,
				    rest = (0, _objectWithoutProperties3.default)(_props, ["onBefore", "onAfter", "onLoaded"]);

				return WrapComponent ? _react2.default.createElement(WrapComponent, (0, _extends3.default)({}, rest, { ref: onLoaded ? function (instance) {
						return onLoaded(instance);
					} : refName })) : Loading ? _react2.default.createElement(Loading, null) : null;
			}
		}]);
		return AsyncComponent;
	}(_react.Component);

	return AsyncComponent;
};