import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
import _createClass from '@babel/runtime/helpers/esm/createClass';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';

/**
 * Provider using globally available, configured Herment instance.
 *
 * @link https://bitbucket.org/atlassian/herment/overview
 */
function hermentHandler(name, properties) {
  try {
    window.AJS.EventQueue.push({
      name: name,
      properties: properties
    });
  } catch (e) {
    // eslint-disable-next-line no-console
    console.warn('Unable to send analytics event via Herment - has it been initialized?', e);
  }
}
function debugHandler(name, properties) {
  // eslint-disable-next-line no-console
  console.info('analytics event: ', name, properties ? properties : '[no properties]');
}

/**
 * Attempt to detect analytics provider.
 */
function detectHandler() {
  // Check Herment is globally available
  if (typeof window !== 'undefined' && window.AJS && window.AJS.EventQueue && typeof window.AJS.EventQueue.push === 'function') {
    return hermentHandler;
  }

  // Unable to detect a suitable handler
  return function () {
    return null;
  };
}

// This declaration is needed for TS to allow invoking Herment queue methods

/**
 * The service allows @analytics annotations to access the analytics Handler
 * from an arbitrary scope. This coupling assumes that there is only one analytics
 * Handler that should be used on the page across all components.
 */
var AnalyticsService = /*#__PURE__*/function () {
  function AnalyticsService() {
    _classCallCheck(this, AnalyticsService);
    // trackEvent: analyticsHandler = (name: string, properties?: analyticsProperties) => {};
    _defineProperty(this, "trackEvent", detectHandler());
  }
  _createClass(AnalyticsService, [{
    key: "handler",
    set: function set(handler) {
      this.trackEvent = handler ? handler : function () {};
    }
  }]);
  return AnalyticsService;
}();
var analyticsService = new AnalyticsService();

function commandWithAnalytics(analyticsEventName, properties) {
  return function (command) {
    return function (state, dispatch, view) {
      return command(state, function (tr) {
        if (dispatch) {
          analyticsService.trackEvent(analyticsEventName, properties);
          dispatch(tr);
        }
      }, view);
    };
  };
}

/**
 * Returns a sequence of tracking analytics event and the provided function.
 *
 * Usage:
 *
 *     let doSomething = function(a, b) { // ... }
 *     doSomething = trackAndInvoke('uidu.editor-core.dosomething', doSomething);
 *
 *     doSomething(); // This will send analytics event and call the original function.
 *
 */
function trackAndInvoke(analyticsEventName, fn) {
  return function (a, b, c, d) {
    var result = fn(a, b, c, d);
    if (result) {
      analyticsService.trackEvent(analyticsEventName);
    }
    return result;
  };
}

function withAnalytics(analyticsEventName, trackedFn) {
  return function () {
    var result = trackedFn.apply(void 0, arguments);
    if (result) {
      try {
        analyticsService.trackEvent(analyticsEventName);
      } catch (e) {
        // eslint-disable-next-line no-console
        console.error('An exception has been thrown when trying to track analytics event:', e);
      }
    }
    return result;
  };
}

export { analyticsService as a, detectHandler as b, commandWithAnalytics as c, debugHandler as d, hermentHandler as h, trackAndInvoke as t, withAnalytics as w };
