/* === Version detector ===
   Soft banner that prompts a refresh when a new build is deployed.
   Helps for Electron tabs that stay open for days, web users sitting
   on long sessions, and any case where the browser cache is fresh
   enough to skip revalidation.

   Detection mechanism: at load time we capture the set of `?v=N`
   query strings on the JSX scripts currently running. Periodically
   (and on window focus) we fetch the live index.html, parse it, and
   compare against the captured set. Any mismatch means new code has
   shipped. No version.json, no build-time stamping — the existing
   cache-busting query strings ARE the version, transparently.

   Cadence:
     - First check 30s after load (lets the page settle, avoids
       checking before Vercel's CDN sync is complete during tight
       deploy windows)
     - Every 5 minutes thereafter
     - Every time the window regains focus (Electron pattern: user
       comes back to the app → that's when we want to nag)
   Once we've detected an update, polling stops; the banner stays
   visible until they click Refresh.
*/

function _versionFingerprint(root) {
  // Use the JSX script src attributes as a build fingerprint. Sort
  // for stability — script tag order in the HTML shouldn't matter.
  return Array.from(root.querySelectorAll('script[src*=".jsx?v="]'))
    .map(s => s.getAttribute('src'))
    .sort()
    .join(',');
}

function useVersionCheck() {
  const [needsUpdate, setNeedsUpdate] = React.useState(false);

  // Capture the local fingerprint ONCE at mount — it's whatever the
  // page loaded with and won't change at runtime.
  const localVersion = React.useMemo(() => _versionFingerprint(document), []);

  React.useEffect(() => {
    if (needsUpdate) return;             // Already detected; stop polling.
    if (!localVersion) return;           // Nothing to compare against.

    let cancelled = false;

    const check = async () => {
      try {
        // Cache-busting query so we never serve a stale HTML body.
        const r = await fetch('/?_versioncheck=' + Date.now(), { cache: 'no-cache' });
        if (!r.ok || cancelled) return;
        const html = await r.text();
        const doc = new DOMParser().parseFromString(html, 'text/html');
        const remoteVersion = _versionFingerprint(doc);
        if (cancelled) return;
        if (remoteVersion && remoteVersion !== localVersion) {
          setNeedsUpdate(true);
        }
      } catch {
        // Network failures are silent — try again next interval.
      }
    };

    const initialTimer = setTimeout(check, 30 * 1000);
    const interval = setInterval(check, 5 * 60 * 1000);
    const onFocus = () => check();
    const onVisibility = () => { if (!document.hidden) check(); };
    window.addEventListener('focus', onFocus);
    document.addEventListener('visibilitychange', onVisibility);

    return () => {
      cancelled = true;
      clearTimeout(initialTimer);
      clearInterval(interval);
      window.removeEventListener('focus', onFocus);
      document.removeEventListener('visibilitychange', onVisibility);
    };
  }, [needsUpdate, localVersion]);

  return needsUpdate;
}

function VersionUpdateBanner() {
  const needsUpdate = useVersionCheck();
  if (!needsUpdate) return null;
  return (
    <div className="version-update-banner" role="status" aria-live="polite">
      <span className="version-update-dot" aria-hidden="true" />
      <span className="version-update-message">
        A newer version of homebook is available.
      </span>
      <button className="btn version-update-refresh"
              onClick={() => window.location.reload()}>
        Refresh
      </button>
    </div>
  );
}

Object.assign(window, { VersionUpdateBanner, useVersionCheck });
