"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = require("react-dom");
var _linkExtractors = require("@atlaskit/link-extractors");
var _linkProvider = require("@atlaskit/link-provider");
var _useAnalyticsEvents2 = require("../../common/analytics/generated/use-analytics-events");
var _useIncomingOutgoingLinks = _interopRequireDefault(require("../../state/hooks/use-incoming-outgoing-links"));
var _useResponse2 = _interopRequireDefault(require("../../state/hooks/use-response"));
var _RelatedLinksBaseModal = _interopRequireDefault(require("./components/RelatedLinksBaseModal"));
var _errored = _interopRequireDefault(require("./views/errored"));
var _resolved = _interopRequireDefault(require("./views/resolved"));
var _resolving = _interopRequireDefault(require("./views/resolving"));
var _unavailable = _interopRequireDefault(require("./views/unavailable"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
var isGrantedResponse = function isGrantedResponse(response) {
  var _response$body$meta;
  return 'body' in response && ((_response$body$meta = response.body.meta) === null || _response$body$meta === void 0 ? void 0 : _response$body$meta.access) === 'granted';
};
var RelatedLinksModal = function RelatedLinksModal(_ref) {
  var onClose = _ref.onClose,
    showModal = _ref.showModal,
    ari = _ref.ari,
    baseUriWithNoTrailingSlash = _ref.baseUriWithNoTrailingSlash;
  var RELATED_LINKS_LENGTH = 5;
  var _useIncomingOutgoingA = (0, _useIncomingOutgoingLinks.default)(baseUriWithNoTrailingSlash),
    getIncomingOutgoingAris = _useIncomingOutgoingA.getIncomingOutgoingAris;
  var _useSmartLinkContext = (0, _linkProvider.useSmartLinkContext)(),
    connections = _useSmartLinkContext.connections;
  var _useResponse = (0, _useResponse2.default)(),
    handleResolvedLinkResponse = _useResponse.handleResolvedLinkResponse;
  var _useAnalyticsEvents = (0, _useAnalyticsEvents2.useAnalyticsEvents)(),
    fireEvent = _useAnalyticsEvents.fireEvent;
  var _useState = (0, _react.useState)([]),
    _useState2 = (0, _slicedToArray2.default)(_useState, 2),
    incomingLinks = _useState2[0],
    setIncomingLinks = _useState2[1];
  var _useState3 = (0, _react.useState)([]),
    _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
    outgoingLinks = _useState4[0],
    setOutgoingLinks = _useState4[1];
  var _useState5 = (0, _react.useState)('loading'),
    _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
    modalStatus = _useState6[0],
    setModalStatus = _useState6[1];

  /**
   * resolves the given ARIs to JSONLD and stores in store using the url present in the JSONLD
   * on successful resolve, it takes the url from the response and dispatches a resolve action
   * on a fail resolve, it is ignored as dispatch error takes in an url that we do not have
   */
  var resolveAris = (0, _react.useCallback)( /*#__PURE__*/function () {
    var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(aris) {
      var urlArray, batchResponse, _iterator, _step, res, url, _t;
      return _regenerator.default.wrap(function (_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            if (!(aris.length === 0)) {
              _context.next = 1;
              break;
            }
            return _context.abrupt("return", []);
          case 1:
            urlArray = [];
            _context.next = 2;
            return connections.client.fetchDataAris(aris);
          case 2:
            batchResponse = _context.sent;
            _iterator = _createForOfIteratorHelper(batchResponse);
            _context.prev = 3;
            _iterator.s();
          case 4:
            if ((_step = _iterator.n()).done) {
              _context.next = 9;
              break;
            }
            res = _step.value;
            if (isGrantedResponse(res)) {
              _context.next = 5;
              break;
            }
            return _context.abrupt("continue", 8);
          case 5:
            if (res.body.data) {
              _context.next = 6;
              break;
            }
            return _context.abrupt("continue", 8);
          case 6:
            url = 'url' in res.body.data && (0, _linkExtractors.extractLink)(res.body.data);
            if (url) {
              _context.next = 7;
              break;
            }
            return _context.abrupt("continue", 8);
          case 7:
            handleResolvedLinkResponse(url, res.body, false, false);
            urlArray.push(url);
          case 8:
            _context.next = 4;
            break;
          case 9:
            _context.next = 11;
            break;
          case 10:
            _context.prev = 10;
            _t = _context["catch"](3);
            _iterator.e(_t);
          case 11:
            _context.prev = 11;
            _iterator.f();
            return _context.finish(11);
          case 12:
            return _context.abrupt("return", urlArray);
          case 13:
          case "end":
            return _context.stop();
        }
      }, _callee, null, [[3, 10, 11, 12]]);
    }));
    return function (_x) {
      return _ref2.apply(this, arguments);
    };
  }(), [connections.client, handleResolvedLinkResponse]);

  /**
   * Gets incoming outgoing ARI's for the given ARI and resolves them to JSONLD
   * throws when request to both incoming and outgoing requests error out
   */
  var fetchIncomingOutgoingData = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
    var _yield$getIncomingOut, incomingAris, outgoingAris, incomingRejected, outGoingRejected, _yield$Promise$all, _yield$Promise$all2, incomingUrls, outgoingUrls;
    return _regenerator.default.wrap(function (_context2) {
      while (1) switch (_context2.prev = _context2.next) {
        case 0:
          _context2.next = 1;
          return getIncomingOutgoingAris(ari);
        case 1:
          _yield$getIncomingOut = _context2.sent;
          incomingAris = _yield$getIncomingOut.incomingAris;
          outgoingAris = _yield$getIncomingOut.outgoingAris;
          incomingRejected = false;
          outGoingRejected = false;
          _context2.next = 2;
          return Promise.all([resolveAris(incomingAris).catch(function () {
            incomingRejected = true;
          }), resolveAris(outgoingAris).catch(function () {
            outGoingRejected = true;
          })]);
        case 2:
          _yield$Promise$all = _context2.sent;
          _yield$Promise$all2 = (0, _slicedToArray2.default)(_yield$Promise$all, 2);
          incomingUrls = _yield$Promise$all2[0];
          outgoingUrls = _yield$Promise$all2[1];
          if (!(incomingRejected && outGoingRejected)) {
            _context2.next = 3;
            break;
          }
          throw new Error('both incoming and outgoing resolve request were rejected');
        case 3:
          return _context2.abrupt("return", {
            incomingUrls: incomingUrls !== null && incomingUrls !== void 0 ? incomingUrls : [],
            outgoingUrls: outgoingUrls !== null && outgoingUrls !== void 0 ? outgoingUrls : []
          });
        case 4:
        case "end":
          return _context2.stop();
      }
    }, _callee2);
  })), [ari, getIncomingOutgoingAris, resolveAris]);
  (0, _react.useEffect)(function () {
    if (!ari) {
      setModalStatus('error');
      fireEvent('operational.relatedLinks.failed', {
        reason: 'ARI empty'
      });
      return;
    }
    fetchIncomingOutgoingData().then(function (_ref4) {
      var incomingUrls = _ref4.incomingUrls,
        outgoingUrls = _ref4.outgoingUrls;
      //Need either one of incoming/outgoing to have item(s) to be resolved
      if (incomingUrls.length + outgoingUrls.length) {
        // we are only rendering the first 5 links that are returned from our request
        (0, _reactDom.unstable_batchedUpdates)(function () {
          setIncomingLinks(incomingUrls.slice(0, RELATED_LINKS_LENGTH));
          setOutgoingLinks(outgoingUrls.slice(0, RELATED_LINKS_LENGTH));
        });
        setModalStatus('resolved');
      } else {
        // if no links are found then render unavailable view
        setModalStatus('unavailable');
      }
      fireEvent('operational.relatedLinks.success', {
        incomingCount: incomingUrls.length,
        outgoingCount: outgoingUrls.length
      });
    }).catch(function (_error) {
      setModalStatus('error');
      fireEvent('operational.relatedLinks.failed', {
        reason: 'Failed to fetch related links'
      });
    });
  }, [ari, connections.client, fetchIncomingOutgoingData, fireEvent, getIncomingOutgoingAris, handleResolvedLinkResponse]);
  var renderView = function renderView() {
    switch (modalStatus) {
      case 'error':
        return /*#__PURE__*/_react.default.createElement(_errored.default, null);
      case 'resolved':
        return /*#__PURE__*/_react.default.createElement(_resolved.default, {
          incomingLinks: incomingLinks,
          outgoingLinks: outgoingLinks
        });
      case 'unavailable':
        return /*#__PURE__*/_react.default.createElement(_unavailable.default, null);
      default:
        return /*#__PURE__*/_react.default.createElement(_resolving.default, null);
    }
  };
  return /*#__PURE__*/_react.default.createElement(_RelatedLinksBaseModal.default, {
    onClose: onClose,
    showModal: showModal
  }, renderView());
};
var _default = exports.default = RelatedLinksModal;