/*! Copyright 2026 Fonticons, Inc. - https://webawesome.com/license */
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
import { html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { WaIntersectEvent } from "../../events/intersect.js";
import { clamp } from "../../internal/math.js";
import { parseSpaceDelimitedTokens } from "../../internal/parse.js";
import { watch } from "../../internal/watch.js";
import WebAwesomeElement from "../../internal/webawesome-element.js";
import styles from "./intersection-observer.styles.js";
let WaIntersectionObserver = class extends WebAwesomeElement {
  constructor() {
    super(...arguments);
    this.intersectionObserver = null;
    this.observedElements = /* @__PURE__ */ new Map();
    this.root = null;
    this.rootMargin = "0px";
    this.threshold = "0";
    this.intersectClass = "";
    this.once = false;
    this.disabled = false;
  }
  connectedCallback() {
    super.connectedCallback();
    if (!this.disabled) {
      this.updateComplete.then(() => {
        this.startObserver();
      });
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.stopObserver();
  }
  handleSlotChange() {
    if (!this.disabled) {
      this.startObserver();
    }
  }
  /** Converts threshold property string into numeric array. */
  parseThreshold() {
    const tokens = parseSpaceDelimitedTokens(this.threshold);
    return tokens.map((token) => {
      const num = parseFloat(token);
      return isNaN(num) ? 0 : clamp(num, 0, 1);
    });
  }
  /** Locates and returns the root element using the specified ID. */
  resolveRoot() {
    if (!this.root) return null;
    try {
      const doc = this.getRootNode();
      const target = doc.getElementById(this.root);
      if (!target) {
        console.warn(`Root element with ID "${this.root}" could not be found.`, this);
      }
      return target;
    } catch {
      console.warn(`Invalid selector for root: "${this.root}"`, this);
      return null;
    }
  }
  /** Initializes or reinitializes the intersection observer instance. */
  startObserver() {
    this.stopObserver();
    if (this.disabled) return;
    const threshold = this.parseThreshold();
    const rootElement = this.resolveRoot();
    this.intersectionObserver = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          const wasIntersecting = this.observedElements.get(entry.target) ?? false;
          const isIntersecting = entry.isIntersecting;
          this.observedElements.set(entry.target, isIntersecting);
          if (this.intersectClass) {
            if (isIntersecting) {
              entry.target.classList.add(this.intersectClass);
            } else {
              entry.target.classList.remove(this.intersectClass);
            }
          }
          const changeEvent = new WaIntersectEvent({ entry });
          this.dispatchEvent(changeEvent);
          if (isIntersecting && !wasIntersecting) {
            if (this.once) {
              this.intersectionObserver?.unobserve(entry.target);
              this.observedElements.delete(entry.target);
            }
          }
        });
      },
      {
        root: rootElement,
        rootMargin: this.rootMargin,
        threshold
      }
    );
    const slot = this.shadowRoot.querySelector("slot");
    if (slot !== null) {
      const elements = slot.assignedElements({ flatten: true });
      elements.forEach((element) => {
        this.intersectionObserver?.observe(element);
        this.observedElements.set(element, false);
      });
    }
  }
  /** Halts the intersection observer and cleans up. */
  stopObserver() {
    if (this.intersectClass) {
      this.observedElements.forEach((_, element) => {
        element.classList.remove(this.intersectClass);
      });
    }
    this.intersectionObserver?.disconnect();
    this.intersectionObserver = null;
    this.observedElements.clear();
  }
  handleDisabledChange() {
    if (this.disabled) {
      this.stopObserver();
    } else {
      this.startObserver();
    }
  }
  handleOptionsChange() {
    this.startObserver();
  }
  render() {
    return html` <slot @slotchange=${this.handleSlotChange}></slot> `;
  }
};
WaIntersectionObserver.css = styles;
__decorateClass([
  property()
], WaIntersectionObserver.prototype, "root", 2);
__decorateClass([
  property({ attribute: "root-margin" })
], WaIntersectionObserver.prototype, "rootMargin", 2);
__decorateClass([
  property()
], WaIntersectionObserver.prototype, "threshold", 2);
__decorateClass([
  property({ attribute: "intersect-class" })
], WaIntersectionObserver.prototype, "intersectClass", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], WaIntersectionObserver.prototype, "once", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], WaIntersectionObserver.prototype, "disabled", 2);
__decorateClass([
  watch("disabled", { waitUntilFirstUpdate: true })
], WaIntersectionObserver.prototype, "handleDisabledChange", 1);
__decorateClass([
  watch("root", { waitUntilFirstUpdate: true }),
  watch("rootMargin", { waitUntilFirstUpdate: true }),
  watch("threshold", { waitUntilFirstUpdate: true })
], WaIntersectionObserver.prototype, "handleOptionsChange", 1);
WaIntersectionObserver = __decorateClass([
  customElement("wa-intersection-observer")
], WaIntersectionObserver);
export {
  WaIntersectionObserver as default
};
