"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _globals = require("@jest/globals");
var _jestDiff = require("jest-diff");
var _matches = _interopRequireDefault(require("lodash/matches"));
/* eslint-disable @typescript-eslint/no-namespace */

var isObject = function isObject(x) {
  return (0, _typeof2.default)(x) === 'object' && x !== null;
};
var objectHas = function objectHas(x, prop) {
  return isObject(x) && prop in x;
};
_globals.expect.extend({
  toBeFiredWithAnalyticEventOnce: function toBeFiredWithAnalyticEventOnce(spy, event, channel) {
    var _this = this;
    /**
     * Find all events that match the comparison event
     */
    var matchingEvents = spy.mock.calls.filter(function (arg) {
      return (0, _matches.default)(event)(arg[0]);
    });

    /**
     * We only pass if we can find a single matching event
     */
    if (matchingEvents.length === 1) {
      /**
       * The single matching event must be fired on the channel specified, else is not a pass
       */
      if (channel && matchingEvents[0][1] !== channel) {
        return {
          message: function message() {
            return _this.utils.matcherHint('toBeFiredWithAnalyticEventOnce') + '\n\n' + "Expected to fire on: ".concat(_this.utils.printExpected(channel), ",\n") + "Actually fired on: ".concat(_this.utils.printReceived(matchingEvents[0][1]));
          },
          pass: false
        };
      }
      return {
        message: function message() {
          return "analytic event was fired once";
        },
        pass: true
      };
    }
    return {
      message: function message() {
        if (spy.mock.calls.length === 0) {
          return "no events were fired!";
        }
        var candidates = spy.mock.calls.filter(function (parameters) {
          var e = parameters === null || parameters === void 0 ? void 0 : parameters[0];
          if (objectHas(e, 'payload') && objectHas(e.payload, 'action') && objectHas(e.payload, 'actionSubject') && objectHas(event, 'payload') && objectHas(event.payload, 'action') && objectHas(event.payload, 'actionSubject')) {
            return e.payload.action === event.payload.action && e.payload.actionSubject === event.payload.actionSubject;
          }
          return false;
        });
        if (candidates.length === 0) {
          return _this.utils.matcherHint('toBeFiredWithAnalyticEventOnce', undefined, undefined) + '\n\n' + "Event Expected: \n\n".concat(JSON.stringify(event), "\n\n") + "Events Received: \n\n".concat(spy.mock.calls.map(function (_ref, i) {
            var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
              x = _ref2[0];
            if (x.payload.eventType === 'screen') {
              return "".concat(i, ": ").concat(x.payload.name, " ").concat(x.payload.action);
            }
            return "".concat(i, ": ").concat(x.payload.actionSubject, " ").concat(x.payload.action);
          }).join('\n'));
        }
        if (candidates.length === 1) {
          var difference = (0, _jestDiff.diff)(event, candidates[0][0]);
          return _this.utils.matcherHint('toBeFiredWithAnalyticEventOnce', undefined, undefined) + '\n\n' + "Expected: ".concat(JSON.stringify(event), "\n\n") + "Received: ".concat(spy.mock.calls.map(function (_ref3) {
            var _ref4 = (0, _slicedToArray2.default)(_ref3, 1),
              x = _ref4[0];
            return "".concat(JSON.stringify(x));
          }).join('\n\n')) + "".concat(difference);
        }
        return _this.utils.matcherHint('toBeFiredWithAnalyticEventOnce', undefined, undefined) + '\n\n' + "Expected: ".concat(JSON.stringify(event), "\n") + "Received: ".concat(candidates.map(function (_ref5) {
          var _ref6 = (0, _slicedToArray2.default)(_ref5, 1),
            x = _ref6[0];
          return "".concat(JSON.stringify(x));
        }).join('\n\n'));
      },
      pass: false
    };
  }
});