'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

import warning from 'warning';
import { canUseDOM } from './ExecutionEnvironment';
import { addEventListener, removeEventListener } from './DOMUtils';
import deprecate from './deprecate';

function startBeforeUnloadListener(getBeforeUnloadPromptMessage) {
  function listener(event) {
    var message = getBeforeUnloadPromptMessage();

    if (typeof message === 'string') {
      (event || window.event).returnValue = message;
      return message;
    }
  }

  addEventListener(window, 'beforeunload', listener);

  return function () {
    removeEventListener(window, 'beforeunload', listener);
  };
}

/**
 * Returns a new createHistory function that can be used to create
 * history objects that know how to use the beforeunload event in web
 * browsers to cancel navigation.
 */
function useBeforeUnload(createHistory) {
  return function (options) {
    var history = createHistory(options);

    var stopBeforeUnloadListener = undefined;
    var beforeUnloadHooks = [];

    function getBeforeUnloadPromptMessage() {
      var message = undefined;

      for (var i = 0, len = beforeUnloadHooks.length; message == null && i < len; ++i) {
        message = beforeUnloadHooks[i].call();
      }return message;
    }

    function listenBeforeUnload(hook) {
      beforeUnloadHooks.push(hook);

      if (beforeUnloadHooks.length === 1) {
        if (canUseDOM) {
          stopBeforeUnloadListener = startBeforeUnloadListener(getBeforeUnloadPromptMessage);
        } else {
          process.env.NODE_ENV !== 'production' ? warning(false, 'listenBeforeUnload only works in DOM environments') : undefined;
        }
      }

      return function () {
        beforeUnloadHooks = beforeUnloadHooks.filter(function (item) {
          return item !== hook;
        });

        if (beforeUnloadHooks.length === 0 && stopBeforeUnloadListener) {
          stopBeforeUnloadListener();
          stopBeforeUnloadListener = null;
        }
      };
    }

    // deprecated
    function registerBeforeUnloadHook(hook) {
      if (canUseDOM && beforeUnloadHooks.indexOf(hook) === -1) {
        beforeUnloadHooks.push(hook);

        if (beforeUnloadHooks.length === 1) stopBeforeUnloadListener = startBeforeUnloadListener(getBeforeUnloadPromptMessage);
      }
    }

    // deprecated
    function unregisterBeforeUnloadHook(hook) {
      if (beforeUnloadHooks.length > 0) {
        beforeUnloadHooks = beforeUnloadHooks.filter(function (item) {
          return item !== hook;
        });

        if (beforeUnloadHooks.length === 0) stopBeforeUnloadListener();
      }
    }

    return _extends({}, history, {
      listenBeforeUnload: listenBeforeUnload,

      registerBeforeUnloadHook: deprecate(registerBeforeUnloadHook, 'registerBeforeUnloadHook is deprecated; use listenBeforeUnload instead'),
      unregisterBeforeUnloadHook: deprecate(unregisterBeforeUnloadHook, 'unregisterBeforeUnloadHook is deprecated; use the callback returned from listenBeforeUnload instead')
    });
  };
}

export default useBeforeUnload;