import { Component, getChildrenFragment } from "/js/components/component.js";

class InfiniteScrollContainer extends Component {
  static get observedAttributes() {
    return ["disabled"];
  }

  connectedCallback() {
    if (this._initialized) {
      return;
    }
    this.label = this.getAttribute("label");
    this.expanded = false;
    this._children = getChildrenFragment(this);
    this.lookahead = this.getAttribute("lookahead") ?? "2000px";
    this.inverted = this.hasAttribute("inverted");
    this.innerHTML = "";
    this.render();
    this._initialized = true;
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === "disabled" && this.observer && this.sentinel) {
      if (this.hasAttribute("disabled")) {
        this.observer.unobserve(this.sentinel);
      } else {
        this.observer.observe(this.sentinel);
      }
    }
  }

  disconnectedCallback() {
    if (this.observer) {
      this.observer.disconnect();
    }
  }

  render() {
    const container = document.createElement("div");
    container.classList.add("infinite-scroll-container");
    container.style.cssText = `
      position: relative;
    `;
    this.appendChild(container);
    container.appendChild(this._children);

    const sentinel = document.createElement("div");
    sentinel.classList.add("infinite-scroll-sentinel");
    const sentinelPosition = this.inverted ? "top: 0;" : "bottom: 0;";
    sentinel.style.cssText = `
      position: absolute;
      ${sentinelPosition}
      width: 1px;
      height: ${this.lookahead};
      max-height: 100%;
      background-color: transparent;
      pointer-events: none;
    `;

    if (this.inverted) {
      container.insertBefore(sentinel, container.firstChild);
    } else {
      container.appendChild(sentinel);
    }

    this.sentinel = sentinel;
    this.observer = this.initializeObserver(sentinel);
  }

  initializeObserver(sentinel) {
    const options = {
      threshold: 0,
    };

    const observer = new IntersectionObserver((entries) => {
      const entry = entries[0];
      if (!entry) return;

      if (entry.isIntersecting && !this.hasAttribute("disabled")) {
        // Pause observing during load
        this.observer.unobserve(sentinel);

        this.dispatchEvent(
          new CustomEvent("load-more", {
            detail: {
              resume: () => {
                // Re-observe after the DOM/layout settles
                if (!this.hasAttribute("disabled")) {
                  requestAnimationFrame(() => {
                    // Force a reflow guard (GPT says this could help with iOS Safari)
                    sentinel.offsetTop;
                    this.observer.observe(sentinel);
                  });
                }
              },
            },
          }),
        );
      }
    }, options);

    if (!this.hasAttribute("disabled")) {
      requestAnimationFrame(() => observer.observe(sentinel));
    }

    return observer;
  }
}

InfiniteScrollContainer.register();
