(function () {
  "use strict";

  function sessionTimeout(options) {
    var defaults = {
      title: "Are you still there?",
      message: "Your session is about to expire.",
      logoutButton: "Logout",
      keepAliveButton: "Stay Connected",
      keepAliveUrl: ROOT_URL + "/src/js/keep_alive.php",
      ajaxType: "POST",
      ajaxData: "tenant=" + TENANT_URL,
      redirUrl: "index.php?op=logout&msg=timeout",
      logoutUrl: "index.php?op=logout",
      warnAfter: 900000, // 15 minutes 900000
      redirAfter: 1200000, // 20 minutes 1200000
      keepAliveInterval: 50000, //50000
      keepAlive: true,
      ignoreUserActivity: false,
      onStart: false,
      onWarn: false,
      onRedir: false,
      countdownMessage: "This session will close in {timer} seconds.",
      countdownBar: true,
      countdownSmart: true,
    };

    var opt = Object.assign({}, defaults, options);
    var timer,
      countdown = {};

    if (opt.warnAfter >= opt.redirAfter) {
      console.error('Option "redirAfter" must be equal or greater than "warnAfter".');
      return false;
    }

    if (typeof opt.onWarn !== "function") {
      var countdownMessage = opt.countdownMessage ? "<p>" + opt.countdownMessage.replace(/{timer}/g, '<span class="cnt countdown-holder"></span>') + "</p>" : "";
      var countdownBarHtml = opt.countdownBar ? '<div class="progress"><div class="progress-bar progress-bar-striped countdown-bar active" role="progressbar" style="min-width: 15px; width: 100%;"><span class="countdown-holder"></span></div></div>' : "";

      document.body.insertAdjacentHTML(
        "beforeend",
        `
          <div class="modal fade" id="session-timeout-dialog" tabindex="-1">
            <div class="modal-dialog">
              <div class="modal-content">
                <div class="modal-header" style="background-color: #2a3f54; color:#fff">
                  <h4 class="modal-title"><img src="${ROOT_URL}/images/logoSm.png" class="mr-3"> ${opt.title}</h4>
                  
                </div>
                <div class="modal-body">
                  <p class="lead">${opt.message}</p>
                  ${countdownMessage}
                  ${countdownBarHtml}
                </div>
                <div class="modal-footer">
                  <button id="session-timeout-dialog-logout" type="button" class="btn btn-danger px-3 py-2">${opt.logoutButton}</button>
                  <button id="session-timeout-dialog-keepalive" type="button" class="btn btn-success px-3 py-2" data-mdb-dismiss="modal">${opt.keepAliveButton}</button>
                </div>
              </div>
            </div>
          </div>`
      );

      document.getElementById("session-timeout-dialog-logout").addEventListener("click", function () {
        window.location = opt.logoutUrl;
      });

      document.getElementById("session-timeout-dialog").addEventListener("hide.bs.modal", function () {
        startSessionTimer();
      });
    }

    if (!opt.ignoreUserActivity) {
      var mousePosition = [-1, -1];
      document.addEventListener("keyup", startSessionTimer);
      document.addEventListener("mouseup", startSessionTimer);
      document.addEventListener("mousemove", function (e) {
        if (e.clientX === mousePosition[0] && e.clientY === mousePosition[1]) {
          return;
        }
        mousePosition[0] = e.clientX;
        mousePosition[1] = e.clientY;
        startSessionTimer();
      });
      document.addEventListener("touchend", startSessionTimer);
      document.addEventListener("touchmove", startSessionTimer);
    }

    var keepAlivePinged = false;

    async function keepAlive() {
      if (!keepAlivePinged) {
        try {
          await fetch(opt.keepAliveUrl, {
            method: opt.ajaxType,
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body: opt.ajaxData,
          });
          keepAlivePinged = true;
          setTimeout(function () {
            keepAlivePinged = false;
          }, opt.keepAliveInterval);
        } catch (error) {
          console.error("Error:", error);
        }
      }
    }

    function startSessionTimer() {
      clearTimeout(timer);
      if (opt.countdownMessage || opt.countdownBar) {
        startCountdownTimer("session", true);
      }

      if (typeof opt.onStart === "function") {
        opt.onStart(opt);
      }

      if (opt.keepAlive) {
        keepAlive();
      }

      timer = setTimeout(function () {
        if (typeof opt.onWarn !== "function") {
          var sessionTimeoutDialog = new mdb.Modal(document.getElementById("session-timeout-dialog"));
          sessionTimeoutDialog.show();
        } else {
          opt.onWarn(opt);
        }
        startDialogTimer();
      }, opt.warnAfter);
    }

    function startDialogTimer() {
      clearTimeout(timer);
      if (!document.getElementById("session-timeout-dialog").classList.contains("show") && (opt.countdownMessage || opt.countdownBar)) {
        startCountdownTimer("dialog", true);
      }
      timer = setTimeout(function () {
        if (typeof opt.onRedir !== "function") {
          window.location = opt.redirUrl;
        } else {
          opt.onRedir(opt);
        }
      }, opt.redirAfter - opt.warnAfter);
    }

    function startCountdownTimer(type, reset) {
      clearTimeout(countdown.timer);

      if (type === "dialog" && reset) {
        countdown.timeLeft = Math.floor((opt.redirAfter - opt.warnAfter) / 1000);
      } else if (type === "session" && reset) {
        countdown.timeLeft = Math.floor(opt.redirAfter / 1000);
      }

      if (opt.countdownBar && type === "dialog") {
        countdown.percentLeft = Math.floor((countdown.timeLeft / ((opt.redirAfter - opt.warnAfter) / 1000)) * 100);
      } else if (opt.countdownBar && type === "session") {
        countdown.percentLeft = Math.floor((countdown.timeLeft / (opt.redirAfter / 1000)) * 100);
      }

      var countdownEl = document.querySelector(".countdown-holder");
      var secondsLeft = countdown.timeLeft >= 0 ? countdown.timeLeft : 0;
      if (opt.countdownSmart) {
        var minLeft = Math.floor(secondsLeft / 60);
        var secRemain = secondsLeft % 60;
        var countTxt = minLeft > 0 ? minLeft + "m" : "";
        if (countTxt.length > 0) {
          countTxt += " ";
        }
        countTxt += secRemain + "s";

        countdownEl.textContent = countTxt;
      } else {
        countdownEl.textContent = secondsLeft + "s";
      }

      if (opt.countdownBar) {
        document.querySelector(".countdown-bar").style.width = countdown.percentLeft + "%";
      }
      if (countdown.timeLeft < 16) {
        document.querySelector(".cnt").style.color = "";
        document.querySelector(".progress-bar").classList.remove("bg-danger");
        document.querySelector(".progress-bar").classList.add("bg-warning");
      }
      if (countdown.timeLeft < 11) {
        document.querySelector(".cnt").style.color = "red";
        document.querySelector(".progress-bar").classList.remove("bg-warning");
        document.querySelector(".progress-bar").classList.add("bg-danger");
      }
      if (countdown.timeLeft > 15) {
        document.querySelector(".cnt").style.color = "";
        document.querySelector(".progress-bar").classList.remove("bg-warning");
        document.querySelector(".progress-bar").classList.remove("bg-danger");
      }

      countdown.timeLeft = countdown.timeLeft - 1;
      countdown.timer = setTimeout(function () {
        startCountdownTimer(type);
      }, 1000);
    }

    startSessionTimer();
  }

  window.sessionTimeout = sessionTimeout;
})();

// Initialize session timeout
sessionTimeout();
