// Capture time-spaced static frames from animated D3 SVG/canvas blocks for print/PDF output.
(function () {
  "use strict";

  const DEFAULT_TIMES_MS = [400, 1800, 3200];

  function parseTimes(raw) {
    if (!raw) return DEFAULT_TIMES_MS.slice();
    const parsed = raw
      .split(",")
      .map((part) => Number(part.trim()))
      .filter((value) => Number.isFinite(value) && value >= 0)
      .sort((a, b) => a - b);

    return parsed.length ? parsed : DEFAULT_TIMES_MS.slice();
  }

  function captureSourceDataUri(sourceEl) {
    if (!sourceEl) return null;
    const tagName = sourceEl.tagName.toLowerCase();

    if (tagName === "canvas") {
      try {
        return sourceEl.toDataURL("image/png");
      } catch (_err) {
        return null;
      }
    }

    if (tagName === "svg") {
      try {
        const clone = sourceEl.cloneNode(true);
        clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
        clone.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");

        const box = sourceEl.getBoundingClientRect();
        if (!clone.getAttribute("width") && box.width > 0) {
          clone.setAttribute("width", String(Math.round(box.width)));
        }
        if (!clone.getAttribute("height") && box.height > 0) {
          clone.setAttribute("height", String(Math.round(box.height)));
        }

        const svgMarkup = new XMLSerializer().serializeToString(clone);
        return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgMarkup)}`;
      } catch (_err) {
        return null;
      }
    }

    return null;
  }

  function buildPrintFrames(container) {
    const sourceSelector = container.dataset.d3PrintSource || "svg,canvas";
    const sourceEl = container.querySelector(sourceSelector);
    if (!sourceEl) return;

    const frameTimes = parseTimes(container.dataset.d3PrintFrames);
    sourceEl.classList.add("d3-print-live-source");

    const groupEl = document.createElement("div");
    groupEl.className = "d3-print-frame-group";
    groupEl.setAttribute("aria-hidden", "true");

    const frames = frameTimes.map((timeMs, index) => {
      const frameEl = document.createElement("div");
      frameEl.className = "d3-print-frame";

      const imgEl = document.createElement("img");
      imgEl.alt = `Animation frame ${index + 1}`;
      imgEl.loading = "lazy";

      frameEl.appendChild(imgEl);
      groupEl.appendChild(frameEl);

      return { index, timeMs, imgEl };
    });

    container.appendChild(groupEl);

    const pending = new Set(frames.map((frame) => frame.index));

    function markReadyIfDone() {
      if (pending.size === 0) {
        container.classList.add("d3-print-frames-ready");
      }
    }

    frames.forEach((frame) => {
      window.setTimeout(() => {
        const uri = captureSourceDataUri(sourceEl);
        if (!uri) return;
        frame.imgEl.src = uri;
        pending.delete(frame.index);
        markReadyIfDone();
      }, frame.timeMs);
    });

    const fallbackDelay = Math.max.apply(null, frameTimes) + 1200;
    window.setTimeout(() => {
      frames.forEach((frame) => {
        if (frame.imgEl.src) return;
        const uri = captureSourceDataUri(sourceEl);
        if (uri) frame.imgEl.src = uri;
      });
      container.classList.add("d3-print-frames-ready");
    }, fallbackDelay);
  }

  document.addEventListener("DOMContentLoaded", () => {
    const containers = document.querySelectorAll("[data-d3-print-frames]");
    containers.forEach((container) => buildPrintFrames(container));
  });
})();
