"use client";

// src/hooks/ui/use-auto-limit-tags.ts
import { useCallback, useEffect, useRef, useState } from "react";
function useAutoLimitTags({
  count,
  limitTags = "auto",
  placeholder = "",
  reserveInputWidth = true
}) {
  const middleRef = useRef(null);
  const measureRef = useRef(null);
  const textMeasureRef = useRef(null);
  const badgeRef = useRef(null);
  const inputRef = useRef(null);
  const [visibleCount, setVisibleCount] = useState(count);
  const recalculate = useCallback(() => {
    if (limitTags !== "auto") {
      setVisibleCount(Math.min(limitTags, count));
      return;
    }
    const middle = middleRef.current;
    const measure = measureRef.current;
    if (!middle || !measure) {
      setVisibleCount(count);
      return;
    }
    if (count === 0) {
      setVisibleCount(0);
      return;
    }
    const cs = getComputedStyle(middle);
    const padL = parseFloat(cs.paddingLeft) || 0;
    const padR = parseFloat(cs.paddingRight) || 0;
    const gap = parseFloat(cs.gap) || 0;
    const middleW = middle.clientWidth;
    let inputReservedW = 0;
    let trailingGap = 0;
    if (reserveInputWidth) {
      const textW = textMeasureRef.current?.offsetWidth ?? 60;
      const inputMinW = inputRef.current ? parseFloat(getComputedStyle(inputRef.current).minWidth) || 60 : 60;
      inputReservedW = Math.max(textW + 8, inputMinW);
      trailingGap = gap;
    }
    const available = middleW - padL - padR - inputReservedW - trailingGap;
    const tagEls = Array.from(measure.children);
    const widths = tagEls.map((el) => el.offsetWidth);
    let total = 0;
    for (let i = 0; i < widths.length; i++) {
      total += widths[i] + (i > 0 ? gap : 0);
    }
    if (total <= available) {
      setVisibleCount(count);
      return;
    }
    const badgeW = badgeRef.current?.offsetWidth ?? 40;
    const spaceWithBadge = available - badgeW - gap;
    let used = 0;
    let fitCount = 0;
    for (let i = 0; i < widths.length; i++) {
      const need = widths[i] + (i > 0 ? gap : 0);
      if (used + need > spaceWithBadge) break;
      used += need;
      fitCount++;
    }
    setVisibleCount(Math.max(0, fitCount));
  }, [count, limitTags, placeholder, reserveInputWidth]);
  useEffect(() => {
    recalculate();
  }, [recalculate]);
  useEffect(() => {
    const el = middleRef.current;
    if (!el) return;
    const ro = new ResizeObserver(recalculate);
    ro.observe(el);
    return () => ro.disconnect();
  }, [recalculate]);
  return { visibleCount, middleRef, measureRef, textMeasureRef, badgeRef, inputRef };
}

// src/hooks/ui/use-debounce.ts
import { useState as useState2, useEffect as useEffect2 } from "react";
function useDebounce(value, delay = 500) {
  const [debouncedValue, setDebouncedValue] = useState2(value);
  useEffect2(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);
  return debouncedValue;
}

// src/hooks/use-near-viewport.ts
import { useEffect as useEffect3, useRef as useRef2, useState as useState3, useCallback as useCallback2 } from "react";
var observers = /* @__PURE__ */ new Map();
var subscribers = /* @__PURE__ */ new WeakMap();
function getObserverFor(rootMargin) {
  const existing = observers.get(rootMargin);
  if (existing) return existing;
  const io = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return;
        const cb = subscribers.get(entry.target);
        if (cb) {
          cb();
          io.unobserve(entry.target);
          subscribers.delete(entry.target);
        }
      });
    },
    { rootMargin }
  );
  observers.set(rootMargin, io);
  return io;
}
function useNearViewport(rootMargin = "500px") {
  const [isNear, setIsNear] = useState3(false);
  const elRef = useRef2(null);
  const ref = useCallback2(
    (node) => {
      const prev = elRef.current;
      if (prev) {
        const stillOurs = subscribers.get(prev);
        if (stillOurs) {
          subscribers.delete(prev);
          observers.get(rootMargin)?.unobserve(prev);
        }
      }
      elRef.current = node;
      if (!node) return;
      const cb = () => setIsNear(true);
      subscribers.set(node, cb);
      getObserverFor(rootMargin).observe(node);
    },
    [rootMargin]
  );
  useEffect3(() => {
    return () => {
      const el = elRef.current;
      if (!el) return;
      if (subscribers.get(el)) {
        subscribers.delete(el);
        observers.get(rootMargin)?.unobserve(el);
      }
    };
  }, [rootMargin]);
  return { ref, isNear };
}

// src/hooks/use-og-placeholder.ts
import { useMemo } from "react";
function useOgPlaceholder(buildUrl, title, siteName = "", enabled = true, aspect = "wide") {
  return useMemo(() => {
    if (!enabled || !title) return null;
    const options = {};
    if (siteName) options.site = siteName;
    if (aspect === "square") options.aspect = "square";
    return buildUrl(title, options);
  }, [buildUrl, title, siteName, enabled, aspect]);
}

export {
  useAutoLimitTags,
  useDebounce,
  useNearViewport,
  useOgPlaceholder
};
//# sourceMappingURL=chunk-ZXZJSTNV.js.map