class Sidebar {
  constructor(element) {
    this.element = element;
    this.activeLink = null;

    this.element.addEventListener("click", (e) => {
      // If we click a navigation, close the hamburger menu
      if (
        e.target.tagName == "A" &&
        this.element.classList.contains("sidebar-toggle")
      ) {
        this.element.classList.remove("sidebar-toggle");
        let button = hamburgerToggle.firstElementChild;
        button.textContent = "menu";

        // Scroll a little up to actually see the header
        // Note: this is generally around ~55px
        // A proper solution is getComputedStyle but it can be slow
        // Instead let's just rely on this quirk and call it a day
        // This has to be done after the browser actually processes
        // the section movement
        setTimeout(() => window.scrollBy(0, -100), 75);
      }
    });
  }

  createCollapsableSections() {
    let toc = this.element.querySelector("ul");
    if (!toc) {
      return;
    }
    let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');

    for (let ref of allReferences) {
      let next = ref.nextElementSibling;

      if (next && next.tagName === "UL") {
        let icon = document.createElement("span");
        icon.className = "material-icons collapsible-arrow expanded";
        icon.innerText = "expand_more";

        if (next.parentElement.tagName == "LI") {
          next.parentElement.classList.add("no-list-style");
        }

        icon.addEventListener("click", () => {
          if (icon.classList.contains("expanded")) {
            this.collapseSection(icon);
          } else {
            this.expandSection(icon);
          }
        });

        ref.classList.add("ref-internal-padding");
        ref.parentNode.insertBefore(icon, ref);
      }
    }
  }

  resize() {
    let rect = this.element.getBoundingClientRect();
    this.element.style.height = `calc(100vh - 1em - ${
      rect.top + document.body.offsetTop
    }px)`;
  }

  collapseSection(icon) {
    icon.classList.remove("expanded");
    icon.classList.add("collapsed");
    let children = icon.nextElementSibling.nextElementSibling;
    // <arrow><heading>
    // --> <square><children>
    setTimeout(() => (children.style.display = "none"), 75);
  }

  expandSection(icon) {
    icon.classList.remove("collapse");
    icon.classList.add("expanded");
    let children = icon.nextElementSibling.nextElementSibling;
    setTimeout(() => (children.style.display = "block"), 75);
  }

  setActiveLink(section) {
    if (this.activeLink) {
      this.activeLink.parentElement.classList.remove("active");
    }
    if (section) {
      this.activeLink = document.querySelector(`#sidebar a[href="#${section.id}"]`);
      if (this.activeLink) {
        let headingChildren = this.activeLink.parentElement.parentElement;
        let heading = headingChildren.previousElementSibling.previousElementSibling;

        if (heading && headingChildren.style.display === "none") {
          this.activeLink = heading;
        }
        this.activeLink.parentElement.classList.add("active");
      }
    }
  }
}

function getCurrentSection() {
  let currentSection;
  if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
    currentSection = sections[sections.length - 1];
  } else {
    if (sections) {
      sections.forEach((section) => {
        let rect = section.getBoundingClientRect();
        if (rect.top + document.body.offsetTop < 1) {
          currentSection = section;
        }
      });
    }
  }
  return currentSection;
}

document.addEventListener("DOMContentLoaded", () => {
  sidebar = new Sidebar(document.getElementById("sidebar"));
  sidebar.resize();
  sidebar.createCollapsableSections();

  window.addEventListener("scroll", () => {
    sidebar.setActiveLink(getCurrentSection());
    sidebar.resize();
  });
});
