// gradient-text.jsx
// <GradientText/> — adapted from React Bits (https://reactbits.dev).
// The original depends on motion/react; this project has no bundler (React via
// CDN, JSX transpiled in-browser), so the animation runs on a
// requestAnimationFrame loop writing background-position directly.
// Props match the original API. Rendered with <span>s so it is valid inside
// headings. Exposed via window like tweaks-panel.jsx.
(function () {
  const { useState, useEffect, useRef, useCallback } = React;

  function GradientText({
    children,
    className = "",
    colors = ["#5227FF", "#FF9FFC", "#B497CF"],
    animationSpeed = 8,
    showBorder = false,
    direction = "horizontal",
    pauseOnHover = false,
    yoyo = true,
  }) {
    const [isPaused, setIsPaused] = useState(false);
    const textRef = useRef(null);
    const overlayRef = useRef(null);
    const pausedRef = useRef(false);
    pausedRef.current = isPaused;

    useEffect(() => {
      const duration = animationSpeed * 1000;
      let elapsed = 0;
      let last = null;
      let raf;

      const apply = (p) => {
        const pos = direction === "vertical" ? `50% ${p}%` : `${p}% 50%`;
        if (textRef.current) textRef.current.style.backgroundPosition = pos;
        if (overlayRef.current) overlayRef.current.style.backgroundPosition = pos;
      };

      const tick = (time) => {
        raf = requestAnimationFrame(tick);
        if (pausedRef.current) { last = null; return; }
        if (last === null) { last = time; return; }
        elapsed += time - last;
        last = time;

        if (yoyo) {
          const cycle = elapsed % (duration * 2);
          apply(cycle < duration
            ? (cycle / duration) * 100
            : 100 - ((cycle - duration) / duration) * 100);
        } else {
          apply((elapsed / duration) * 100);
        }
      };

      apply(0);
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, [animationSpeed, direction, yoyo]);

    const handleMouseEnter = useCallback(() => { if (pauseOnHover) setIsPaused(true); }, [pauseOnHover]);
    const handleMouseLeave = useCallback(() => { if (pauseOnHover) setIsPaused(false); }, [pauseOnHover]);

    const gradientAngle =
      direction === "horizontal" ? "to right"
      : direction === "vertical" ? "to bottom"
      : "to bottom right";
    // Duplicate first color at the end for seamless looping
    const gradientColors = [...colors, colors[0]].join(", ");

    const gradientStyle = {
      backgroundImage: `linear-gradient(${gradientAngle}, ${gradientColors})`,
      backgroundSize:
        direction === "horizontal" ? "300% 100%"
        : direction === "vertical" ? "100% 300%"
        : "300% 300%",
      backgroundRepeat: "repeat",
    };

    return (
      <span
        className={`animated-gradient-text ${showBorder ? "with-border" : ""} ${className}`}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave}
      >
        {showBorder && <span ref={overlayRef} className="gradient-overlay" style={gradientStyle} />}
        <span ref={textRef} className="text-content" style={gradientStyle}>
          {children}
        </span>
      </span>
    );
  }

  Object.assign(window, { GradientText });
})();
