Source: versionCheck.js

/**
 * Version change detection and changelog display
 */

/**
 * Compares stored version with current and shows changelog modal if needed
 */
const checkVersionChange = () => {
  const hasData = !!localStorage.getItem(LS_KEY);
  if (!hasData) {
    if (typeof window !== 'undefined' && typeof window.debugLog === "function") window.debugLog("versionCheck: no inventory data, showing ack modal");
    if (typeof showAckModal === "function") {
      showAckModal();
    }
    return;
  }

  const acknowledged = localStorage.getItem(VERSION_ACK_KEY);
  const current = APP_VERSION;
  if (typeof window !== 'undefined' && typeof window.debugLog === "function") {
    window.debugLog(`versionCheck: ack=${acknowledged}, current=${current}, APP_VERSION=${APP_VERSION}`);
  }
  if (acknowledged === current) return;

  if (typeof window !== 'undefined' && typeof window.debugLog === "function") {
    window.debugLog(`versionCheck: mismatch — showing What's New modal`);
  }
  populateVersionModal(current);
};

/**
 * Populates and shows the version modal
 * Content is loaded by loadAnnouncements() into the versionChanges element
 * @param {string} version - Current application version
 */
const populateVersionModal = (version) => {
  const modal = document.getElementById("versionModal");
  const ver = document.getElementById("versionModalVersion");
  if (ver) ver.textContent = `v${version}`;
  if (!modal) return;
  modal.style.display = "flex";
  document.body.style.overflow = "hidden";
  setupVersionModalEvents(version);
  if (typeof loadAnnouncements === "function") {
    loadAnnouncements();
  }
};

/**
 * Sets up modal event handlers for version acknowledgment
 * @param {string} version - Current application version
 */
const setupVersionModalEvents = (version) => {
  const modal = document.getElementById("versionModal");
  const acceptBtn = document.getElementById("versionAcceptBtn");
  const closeBtn = document.getElementById("versionCloseBtn");

  const accept = () => {
    localStorage.setItem(VERSION_ACK_KEY, version);
    if (modal) modal.style.display = "none";
    document.body.style.overflow = "";
  };

  if (acceptBtn) {
    acceptBtn.addEventListener("click", accept);
  }

  if (closeBtn) {
    closeBtn.addEventListener("click", accept);
  }

  if (modal) {
    modal.addEventListener("click", (e) => {
      if (e.target === modal) {
        accept();
      }
    });
  }

  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape" && modal && modal.style.display !== "none" && modal.style.display !== "") {
      accept();
    }
  });
};

/**
 * Compares two BRANCH.RELEASE.PATCH version strings
 * @param {string} a - First version
 * @param {string} b - Second version
 * @returns {number} Negative if a < b, 0 if equal, positive if a > b
 */
const compareVersions = (a, b) => {
  const pa = a.split(".").map(Number);
  const pb = b.split(".").map(Number);
  for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
    const diff = (pa[i] || 0) - (pb[i] || 0);
    if (diff !== 0) return diff;
  }
  return 0;
};

/**
 * Renders the version badge in the footer
 * @param {HTMLElement} badge - The badge element
 * @param {string} remoteVersion - Latest remote version
 * @param {string} releaseUrl - URL to latest release
 */
const renderVersionBadge = (badge, remoteVersion, releaseUrl) => {
  if (!badge) return;
  if (compareVersions(remoteVersion, APP_VERSION) <= 0) {
    badge.textContent = `v${APP_VERSION} up to date`;
    badge.className = "version-badge version-badge--current";
    badge.removeAttribute("href");
    badge.removeAttribute("target");
  } else {
    badge.textContent = `v${remoteVersion} available`;
    badge.className = "version-badge version-badge--update";
    badge.href = releaseUrl;
    badge.target = "_blank";
    badge.rel = "noopener";
  }
  badge.style.display = "";
};

/** @constant {string} GITHUB_RELEASES_URL - Fallback link for static version badge */
const GITHUB_RELEASES_URL = "https://github.com/lbruton/StakTrakr/releases/latest";

/**
 * Shows a static version badge linking to GitHub releases.
 * Used as the default state; upgraded by checkRemoteVersion() when possible.
 */
const showStaticVersionBadge = () => {
  const badge = document.getElementById("versionBadge");
  if (!badge) return;
  badge.textContent = `v${APP_VERSION}`;
  badge.className = "version-badge version-badge--static";
  badge.href = GITHUB_RELEASES_URL;
  badge.target = "_blank";
  badge.rel = "noopener";
  badge.style.display = "";
};

/**
 * Checks for a newer version from the remote version.json endpoint (STACK-67)
 * Skips fetch on file:// protocol (static badge still shown). Caches result for 24 hours.
 */
const checkRemoteVersion = async () => {
  // Always show static badge first as the baseline
  showStaticVersionBadge();

  try {
    // Cannot fetch remote on file:// — keep static badge
    if (window.location.protocol === "file:") return;

    const badge = document.getElementById("versionBadge");
    if (!badge) return;

    // Check 24hr TTL cache
    const lastCheck = localStorage.getItem(LAST_VERSION_CHECK_KEY);
    const cachedVersion = localStorage.getItem(LATEST_REMOTE_VERSION_KEY);
    const cachedUrl = localStorage.getItem(LATEST_REMOTE_URL_KEY);
    if (lastCheck && cachedVersion && Date.now() - Number(lastCheck) < VERSION_CHECK_TTL) {
      renderVersionBadge(badge, cachedVersion, cachedUrl || "");
      return;
    }

    // Fetch with 5s timeout
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), 5000);
    const res = await fetch(VERSION_CHECK_URL, { signal: controller.signal });
    clearTimeout(timeout);
    if (!res.ok) return;

    const data = await res.json();
    const remoteVersion = data.version;
    const releaseUrl = data.releaseUrl || "";
    if (!remoteVersion) return;

    // Cache result
    localStorage.setItem(LAST_VERSION_CHECK_KEY, String(Date.now()));
    localStorage.setItem(LATEST_REMOTE_VERSION_KEY, remoteVersion);
    localStorage.setItem(LATEST_REMOTE_URL_KEY, releaseUrl);

    renderVersionBadge(badge, remoteVersion, releaseUrl);
  } catch (_) {
    // Silent fail — static badge remains visible
  }
};

document.addEventListener("DOMContentLoaded", checkVersionChange);
document.addEventListener("DOMContentLoaded", checkRemoteVersion);