// This used to be based on waiting for a websocket to disconnect, but that was
// flaky. Now we simply poll the shit out of the healthcheck endpoint.
export function initDevReloader(healthzAddr, pollIntervalMs = 500) {
  // State model is implemented with variables and closures.
  let auto = !!sessionStorage.getItem("__dev_reloader_auto");
  let connected = false;
  let initialized = false;
  let interval;

  const button = document.createElement("button");
  const indicator = document.createElement("div");
  const label = document.createElement("div");

  // Rolling our own reactivity: call this after state change to initialize or
  // update DOM view.
  function render() {
    button.style.appearance = "none";
    button.style.background = "#fff";
    button.style.border = "solid 1px #0002";
    button.style.borderRadius = "999px";
    button.style.padding = "1rem";
    button.style.position = "fixed";
    button.style.zIndex = "999";
    button.style.bottom = "1rem";
    button.style.left = "1rem";
    button.style.opacity = "0.5";
    button.style.boxShadow = "0 0.5rem 1rem #0002";
    button.style.display = "flex";
    button.style.cursor = "pointer";
    button.style.alignItems = "center";
    button.style.fontFamily = "sans-serif";

    indicator.style.width = "8px";
    indicator.style.height = "8px";
    indicator.style.borderRadius = "999px";
    indicator.style.background = connected ? "#06f" : "#f60";

    label.style.marginLeft = "1rem";
    label.innerText = auto ? "Disable auto-reload" : "Enable auto-reload";
  }

  function toggleAuto() {
    auto = !auto;
    sessionStorage.setItem("__dev_reloader_auto", auto ? "present" : "");
    if (auto && !interval) {
      startInterval();
    } else if (!auto && interval) {
      clearInterval(interval);
      interval = undefined;
      connected = false;
      initialized = false;
    }
    render();
  }

  function startInterval() {
    interval = setInterval(function () {
      fetch(healthzAddr)
        .then(function () {
          if (!connected) {
            console.log("dev-reloader: connected");
            if (auto && initialized) {
              globalThis.location.reload();
            }
            connected = true;
            initialized = true;
            render();
          }
        })
        .catch(function () {
          if (connected) {
            console.log("dev-reloader: disconnected");
            connected = false;
            render();
          }
        });
    }, pollIntervalMs);
  }

  render();

  button.setAttribute("type", "button");
  button.addEventListener("click", toggleAuto);
  button.appendChild(indicator);
  button.appendChild(label);
  document.body.appendChild(button);

  if (auto) {
    startInterval();
  }
}
