/* globals I18n */

(function() {
  'use strict';

  var expireOn;
  var timeoutID;
  const oneSecondTimeout = 1000;
  const expireLimit = 900000; // 15min in miliseconds

  function padTimeStr(i) {
    var s = ('0' + Math.floor(i));
    return s.substring(s.length - 2);
  }

  function newTimerStr(expirationTime) {
    var m = (expirationTime / 60) % 60;
    var s = (expirationTime % 60);
    return [m, s].map(padTimeStr).join(':');
  }

  function getCurrentTime() {
    var dateNow = new Date();
    return dateNow.getTime();
  }

  function sessionExpireIn() {
    expireOn = window.localStorage.getItem('sessionEnd');
    return expireOn - getCurrentTime();
  }

  function setSessionTimeout(functionCallback, timeoutTime) {
    if (timeoutID) {
      clearTimeout(timeoutID);
    }
    timeoutID = setTimeout(functionCallback, timeoutTime);
  }

  function toggleDocumentTitle(timeString = null) {
    var sleepEmoticon = String.fromCodePoint(0x1F62A);
    var originalTitle = document.title.split(sleepEmoticon).pop().trim();

    if (timeString) {
      document.title = timeString + ' ' + sleepEmoticon + ' ' + originalTitle;
    } else {
      document.title = originalTitle;
    }
  }

  function initializeSessionCountdown() {
    var expirationUrl = $('meta[name=\'expiration-url\']').attr('content');
    var expireIn;
    if (expirationUrl) {
      $.get(expirationUrl, function(data) {
        expireOn = Math.max(window.localStorage.getItem('sessionEnd'), getCurrentTime() + parseInt(data, 10));
        window.localStorage.setItem('sessionEnd', expireOn);
        expireIn = sessionExpireIn();

        if (expireIn <= 0) {
          $('#session-finished').modal();
        } else if (expireIn <= expireLimit + oneSecondTimeout) {
          // eslint-disable-next-line no-use-before-define
          setSessionTimeout(sessionCountdown, oneSecondTimeout);
        } else {
          setSessionTimeout(initializeSessionCountdown, (expireIn - expireLimit));
        }
      });
    }
  }

  function reviveSession() {
    $.post($('meta[name=\'revive-url\']').attr('content'));
    toggleDocumentTitle();
    window.localStorage.removeItem('sessionEnd');
    setSessionTimeout(initializeSessionCountdown, oneSecondTimeout);
  }

  function initializeSessionReviveCallbacks() {
    $('#session-expire').modal().off('hide.bs.modal').on('hide.bs.modal', function() {
      if (sessionExpireIn() > 0 && sessionExpireIn() < expireLimit) {
        reviveSession();
      }
    });

    // for manual page reload
    $(window).off('beforeunload').on('beforeunload', function() {
      if (sessionExpireIn() > 0 && sessionExpireIn() < expireLimit) {
        reviveSession();
      }
    });
  }

  function sessionCountdown() {
    var timeString;
    var expireIn = sessionExpireIn();

    if (!expireOn) {
      initializeSessionCountdown();
    } else if (expireIn > 0 && expireIn <= expireLimit) {
      timeString = newTimerStr(expireIn / 1000);
      toggleDocumentTitle(timeString);
      $('.expiring').text(I18n.t('devise.sessions.expire_modal.session_end_in.header', { time: timeString }));

      if (!$('#session-expire').hasClass('in')) {
        initializeSessionReviveCallbacks();
      }

      setSessionTimeout(sessionCountdown, oneSecondTimeout);
    } else if (expireIn <= 0) {
      toggleDocumentTitle();
      $('#session-expire').modal('hide');
      $('#session-finished').modal();
    }
  }


  window.localStorage.removeItem('sessionEnd');
  setSessionTimeout(initializeSessionCountdown, oneSecondTimeout);

  $(document).on('click', '.session-login', function() {
    window.location.reload();
  });

  $(window).on('storage', (event) => {
    if (event.originalEvent.storageArea !== localStorage) return;
    if (event.originalEvent.key === 'sessionEnd') {
      if (!expireOn && event.originalEvent.newValue) {
        if ($('#session-finished').hasClass('in')) {
          $('#session-finished').modal('hide');
        }
        setSessionTimeout(initializeSessionCountdown, oneSecondTimeout);
      } else if (expireOn && !event.originalEvent.newValue) {
        toggleDocumentTitle();
      }

      expireOn = event.originalEvent.newValue;
      $('#session-expire').modal().off('hide.bs.modal').modal('hide');
    }
  });
}());
