(function () {
  var LIVE_IMAGE = "live/live.png";
  var LIVE_DATA = "live/live.json";
  var REFRESH_MS = 60 * 1000;
  var TICK_MS = 1000;

  var img = document.getElementById("live-feed");
  var timestampEl = document.getElementById("live-timestamp");
  var statUptime = document.getElementById("stat-uptime");
  var statListeners = document.getElementById("stat-listeners");
  var statStatus = document.getElementById("stat-status");
  var lastCapturedAt = null;

  if (!img) {
    return;
  }

  function formatTimeAgo(unixSeconds) {
    var diff = Math.floor(Date.now() / 1000) - unixSeconds;
    if (diff < 0) {
      diff = 0;
    }

    if (diff < 60) {
      return diff === 1 ? "1 second ago" : diff + " seconds ago";
    }

    var minutes = Math.floor(diff / 60);
    if (minutes < 60) {
      return minutes === 1 ? "1 minute ago" : minutes + " minutes ago";
    }

    var hours = Math.floor(diff / 3600);
    if (hours < 24) {
      return hours === 1 ? "1 hour ago" : hours + " hours ago";
    }

    var days = Math.floor(diff / 86400);
    return days === 1 ? "1 day ago" : days + " days ago";
  }

  function formatDuration(seconds) {
    var diff = Math.max(0, Math.floor(seconds));
    var days = Math.floor(diff / 86400);
    var hours = Math.floor((diff % 86400) / 3600);
    var minutes = Math.floor((diff % 3600) / 60);

    if (days > 0) {
      return days + "d " + hours + "h";
    }
    if (hours > 0) {
      return hours + "h " + minutes + "m";
    }
    if (minutes > 0) {
      return minutes + "m";
    }
    return diff + "s";
  }

  function formatUptime(value) {
    if (value === null || value === undefined || value === "") {
      return "---";
    }
    if (typeof value === "number") {
      return formatDuration(value);
    }
    return String(value);
  }

  function formatListeners(value) {
    if (value === null || value === undefined || value === "") {
      return "---";
    }
    return String(value);
  }

  function formatStatus(value) {
    if (value === null || value === undefined || value === "") {
      return "---";
    }
    return String(value);
  }

  function updateTimeAgo() {
    if (!timestampEl) {
      return;
    }

    if (!lastCapturedAt) {
      timestampEl.textContent = "";
      return;
    }

    timestampEl.textContent = "Captured " + formatTimeAgo(lastCapturedAt);
  }

  function updateStats(data) {
    if (statUptime) {
      statUptime.textContent = formatUptime(data.uptime);
    }
    if (statListeners) {
      var listeners = data.listeners;
      if (listeners === undefined) {
        listeners = data.live_listeners;
      }
      statListeners.textContent = formatListeners(listeners);
    }
    if (statStatus) {
      var statusText = formatStatus(data.status);
      statStatus.textContent = statusText;
      statStatus.classList.remove("stat-value--ok", "stat-value--bad");
      if (statusText !== "---" && String(data.status).toLowerCase() !== "online") {
        statStatus.classList.add("stat-value--bad");
      } else if (statusText !== "---") {
        statStatus.classList.add("stat-value--ok");
      }
    }
  }

  function clearStats() {
    updateStats({});
  }

  function fetchLiveData() {
    fetch(LIVE_DATA + "?t=" + Date.now())
      .then(function (response) {
        if (!response.ok) {
          throw new Error("live data unavailable");
        }
        return response.json();
      })
      .then(function (data) {
        if (data && data.timestamp) {
          lastCapturedAt = data.timestamp;
          updateTimeAgo();
        } else {
          lastCapturedAt = null;
          updateTimeAgo();
        }
        updateStats(data || {});
      })
      .catch(function () {
        lastCapturedAt = null;
        updateTimeAgo();
        clearStats();
      });
  }

  function refreshLiveImage() {
    img.src = LIVE_IMAGE + "?t=" + Date.now();
    fetchLiveData();
  }

  img.addEventListener("error", function () {
    img.alt = "Live feed unavailable";
  });

  refreshLiveImage();
  setInterval(refreshLiveImage, REFRESH_MS);
  setInterval(updateTimeAgo, TICK_MS);
})();
