"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.IdleTimeout = void 0;
var _react = require("react");
var _useInterval = _interopRequireDefault(require("./useInterval"));
var _IdleTimeoutDialog = _interopRequireDefault(require("./IdleTimeoutDialog"));
var _checkPassive = require("./utilities/checkPassive");
var _i18n = require("../i18n");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
 *
 * @param timeTilTimeout {number} time in minutes until timeout occurs
 * @returns {string | ReactNode}
 */
const defaultMessageFormatter = timeTilTimeout => {
  const unitOfTime = timeTilTimeout === 1 ? (0, _i18n.t)('idleTimeoutDialog.min') : (0, _i18n.t)('idleTimeoutDialog.mins');
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", {
    children: [(0, _i18n.t)('idleTimeoutDialog.messageLine1'), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), (0, _i18n.t)('idleTimeoutDialog.messageLine2'), /*#__PURE__*/(0, _jsxRuntime.jsxs)("strong", {
      children: [timeTilTimeout, " ", unitOfTime]
    }), ".", /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("br", {}), (0, _i18n.t)('idleTimeoutDialog.continueSessionMessage')]
  });
};

// local storage variable name
const lastActiveCookieName = 'CMS_DS_IT_LAST_ACTIVE';

/**
 * For information about how and when to use this component,
 * [refer to its full documentation page](https://design.cms.gov/components/idle-timeout/).
 */
const IdleTimeout = _ref => {
  let {
    continueSessionText = (0, _i18n.t)('idleTimeoutDialog.continueSessionButtonText'),
    heading = (0, _i18n.t)('idleTimeoutDialog.heading'),
    endSessionButtonText = (0, _i18n.t)('idleTimeoutDialog.endSessionButtonText'),
    endSessionUrl = '/logout',
    formatMessage = defaultMessageFormatter,
    onSessionContinue,
    onSessionForcedEnd,
    onTimeout,
    showSessionEndButton = false,
    timeToTimeout,
    timeToWarning
  } = _ref;
  if (timeToWarning > timeToTimeout) {
    console.error('Error in TimeoutManager component. `timeToWarning` is greater or equal to `timeToTimeout`');
  }
  const msBetweenStatusChecks = 30000;
  // convert minutes to milliseconds
  const msToTimeout = timeToTimeout * 60000;
  const msToWarning = timeToWarning * 60000;
  const [checkStatusTime, setCheckStatusTime] = (0, _react.useState)(null);
  const [showWarning, setShowWarning] = (0, _react.useState)(false);
  const [timeInWarning, setTimeInWarning] = (0, _react.useState)(Math.ceil(timeToTimeout - timeToWarning));

  // cleanup timeouts & intervals
  const clearTimeouts = () => {
    setCheckStatusTime(null);
  };

  // when the countdown for the session ends, clean up, call callback & close modal
  const handleTimeout = () => {
    clearTimeouts();
    removeEventListeners();
    onTimeout();
    setShowWarning(false);
  };

  // when it's time to warn the user about idleness,
  // set an interval that updates the modal message
  const handleWarningTimeout = () => {
    removeEventListeners();
    setShowWarning(true);
  };
  const setTimeoutCookies = () => {
    localStorage.setItem(lastActiveCookieName, Date.now().toString());
    if (checkStatusTime === null) {
      setCheckStatusTime(msBetweenStatusChecks);
    }
  };

  // have to useCallback so that the function can be removed properly from event listeners
  const resetTimeouts = (0, _react.useCallback)(() => {
    clearTimeouts();
    setTimeoutCookies();
  }, []);
  const removeEventListeners = () => {
    document.removeEventListener('mousemove', resetTimeouts);
    document.removeEventListener('keypress', resetTimeouts);
  };
  const addEventListeners = () => {
    const passiveSupported = (0, _checkPassive.checkPassiveSupport)();
    const options = passiveSupported ? {
      passive: true
    } : false;
    document.addEventListener('mousemove', resetTimeouts, options);
    document.addEventListener('keypress', resetTimeouts, options);
  };
  const checkWarningStatus = () => {
    const lastActiveTime = Number(localStorage.getItem(lastActiveCookieName));
    const now = Date.now();
    const msSinceLastActive = now - lastActiveTime;
    if (msSinceLastActive >= msToTimeout) {
      handleTimeout();
    } else if (!showWarning && msSinceLastActive >= msToWarning) {
      removeEventListeners();
      handleWarningTimeout();
    } else if (showWarning && msSinceLastActive >= msToWarning) {
      // if the warning is showing, update the timeInWarning variable (in minutes)
      const minutesLeft = Math.ceil((msToTimeout - msSinceLastActive) / 60000);
      setTimeInWarning(minutesLeft);
    } else if (showWarning && msSinceLastActive < msToWarning) {
      // if another tab updates the last active time, hide current warning modal
      setShowWarning(false);
    }
  };
  (0, _react.useEffect)(() => {
    setTimeoutCookies();
    // event listeners have to be added before status check in case they are removed in status check
    addEventListeners();
    checkWarningStatus();
    return () => {
      clearTimeouts();
      removeEventListeners();
    };
  }, []);
  (0, _react.useEffect)(() => {
    setTimeInWarning(Math.ceil(timeToTimeout - timeToWarning));
    resetTimeouts();
  }, [timeToWarning, timeToTimeout]);

  // setup interval to check status every 30 seconds
  (0, _useInterval.default)(checkWarningStatus, checkStatusTime);
  const handleSessionContinue = () => {
    if (onSessionContinue) {
      onSessionContinue();
    }
    setShowWarning(false);
    setTimeInWarning(Math.ceil(timeToTimeout - timeToWarning));
    resetTimeouts();
    addEventListeners();
  };
  const handleSessionForcedEnd = () => {
    if (onSessionForcedEnd) {
      onSessionForcedEnd();
    } else {
      onTimeout();
    }
    clearTimeouts();
    removeEventListeners();
    setShowWarning(false);
  };
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_IdleTimeoutDialog.default, {
    continueSessionText: continueSessionText,
    heading: heading,
    endSessionButtonText: endSessionButtonText,
    endSessionUrl: endSessionUrl,
    message: formatMessage(timeInWarning),
    onSessionContinue: handleSessionContinue,
    onSessionForcedEnd: handleSessionForcedEnd,
    showSessionEndButton: showSessionEndButton,
    onClose: handleSessionContinue,
    isOpen: showWarning
  });
};
exports.IdleTimeout = IdleTimeout;
var _default = exports.default = IdleTimeout;