/* Minimal Fountain paginated PDF helpers (no marked.min.js). */
(function () {
  window.Marked = window.Marked || {};
  window.Marked.print = window.Marked.print || {};

  function docHeight() {
    return Math.max(
      document.body.scrollHeight || 0,
      document.documentElement.scrollHeight || 0
    );
  }

  function expectedFountainPages() {
    var article = document.querySelector("#wrapper article");
    if (!article) {
      return 0;
    }
    var n = parseInt(article.getAttribute("data-mk-fountain-pages"), 10);
    return isNaN(n) ? 0 : n;
  }

  function blockSelectors() {
    return "#wrapper article p, #wrapper article h1, #wrapper article h2, #wrapper article h3, #wrapper article h4, #wrapper article h5, #wrapper article h6";
  }

  function setPageBreakOffset(el, property, valuePx) {
    if (valuePx === 0) {
      el.style.removeProperty(property);
      return;
    }
    el.style.setProperty(property, valuePx + "px", "important");
  }

  function resetPageBreakOffsets() {
    document.querySelectorAll("#wrapper p.page-break").forEach(function (br) {
      br.style.removeProperty("padding-top");
      br.style.removeProperty("margin-top");
    });
    var wrapper = document.getElementById("wrapper");
    if (wrapper) {
      wrapper.style.paddingBottom = "0px";
    }
  }

  function insertMissingFountainPageBreaks(contentAreaHeight, targetBreakCount) {
    var breaks = document.querySelectorAll("#wrapper p.page-break");
    if (breaks.length >= targetBreakCount) {
      return;
    }

    var blocks = document.querySelectorAll(blockSelectors());
    var pageNum = breaks.length + 2;
    for (var i = 0; i < blocks.length; i++) {
      var el = blocks[i];
      if (el.classList.contains("page-break")) {
        continue;
      }
      var top = el.getBoundingClientRect().top + (window.scrollY || 0);
      var pageIndex = Math.floor(top / contentAreaHeight);
      if (pageIndex < pageNum - 1) {
        continue;
      }

      var pb = document.createElement("p");
      pb.className = "page-break";
      var span = document.createElement("span");
      span.className = "page-number";
      span.textContent = pageNum + ".";
      pb.appendChild(span);
      el.parentNode.insertBefore(pb, el);
      pageNum++;
      breaks = document.querySelectorAll("#wrapper p.page-break");
      if (breaks.length >= targetBreakCount) {
        break;
      }
    }
  }

  function ensureScrollPaddingForPageCount(pageCount, pageHeight) {
    pageCount = Math.max(1, pageCount || 1);
    pageHeight = pageHeight || window.innerHeight || 0;
    if (pageHeight <= 0) {
      return docHeight();
    }
    var minScrollHeight = pageCount * pageHeight;
    var scrollHeight = docHeight();
    var deficit = minScrollHeight - scrollHeight;
    if (deficit <= 0) {
      return scrollHeight;
    }
    var wrapper = document.getElementById("wrapper");
    if (wrapper) {
      var existingPad = parseFloat(wrapper.style.paddingBottom) || 0;
      wrapper.style.paddingBottom = existingPad + deficit + "px";
    }
    return docHeight();
  }

  function paginateFountainDocument(contentAreaHeight) {
    contentAreaHeight =
      contentAreaHeight ||
      window.innerHeight ||
      document.documentElement.clientHeight;

    resetPageBreakOffsets();

    var breaks = document.querySelectorAll("#wrapper p.page-break");
    var expectedPages = expectedFountainPages();
    var targetBreakCount = expectedPages > 1 ? expectedPages - 1 : 0;

    // Only synthesize breaks when the parser supplied a page count but the live
    // preview DOM has none (e.g. export before preview finished paginating).
    if (targetBreakCount > 0 && breaks.length === 0) {
      insertMissingFountainPageBreaks(contentAreaHeight, targetBreakCount);
      breaks = document.querySelectorAll("#wrapper p.page-break");
    }

    var topThreshold = 2;

    for (var pass = 0; pass < 2; pass++) {
      for (var i = 0; i < breaks.length; i++) {
        var el = breaks[i];
        // Break i labels page (i+2); anchor at the top of that page so the number
        // lands in the correct PDF slice (not the last line of the previous page).
        var targetTop = (i + 1) * contentAreaHeight;
        var rect = el.getBoundingClientRect();
        var top = rect.top + (window.scrollY || 0);
        var delta = targetTop - top;

        setPageBreakOffset(el, "padding-top", 0);
        setPageBreakOffset(el, "margin-top", 0);

        if (delta > topThreshold) {
          setPageBreakOffset(el, "padding-top", delta);
        } else if (delta < -topThreshold) {
          setPageBreakOffset(el, "margin-top", delta);
        }
      }
      document.body.offsetHeight;
      breaks = document.querySelectorAll("#wrapper p.page-break");
    }

    document.body.offsetHeight;
    var totalPages =
      breaks.length > 0
        ? breaks.length + 1
        : Math.max(1, Math.ceil(docHeight() / contentAreaHeight));

    ensureScrollPaddingForPageCount(totalPages, contentAreaHeight);
    return totalPages;
  }

  window.Marked.print.paginateFountainDocument = paginateFountainDocument;
  window.Marked.print.ensureScrollPaddingForPageCount =
    ensureScrollPaddingForPageCount;
  window.Marked.print.paginate = function () {
    return 0;
  };
  window.Marked.print.resetPagination = function () {};
})();
