/* GlowCard.jsx — vanilla JSX adaptation of shadcn/Tailwind spotlight-card.
   Gives each child a fixed-position spotlight glow that tracks the mouse,
   plus an animated colored border. No Tailwind: pure CSS via a single
   <style> block injected once.

   Usage:
     <GlowCard glowColor="purple" radius={18} className="my-card">
       ...content...
     </GlowCard>

   glowColor: "blue" | "purple" | "green" | "red" | "orange" | "ember"
*/

const { useEffect: gcUseEffect, useRef: gcUseRef } = React;

const GLOW_COLOR_MAP = {
  blue:   { base: 220, spread: 200 },
  purple: { base: 280, spread: 260 },
  green:  { base: 145, spread: 180 },
  red:    { base:   0, spread: 200 },
  orange: { base:  30, spread: 200 },
  ember:  { base:  18, spread: 220 },
};

// Inject the ::before / ::after spotlight styles ONCE per page
let __gcStylesInjected = false;
function injectGlowStyles() {
  if (__gcStylesInjected || typeof document === "undefined") return;
  __gcStylesInjected = true;
  const css = `
    [data-glow] {
      position: relative;
      isolation: isolate;
    }
    [data-glow]::before,
    [data-glow]::after {
      pointer-events: none;
      content: "";
      position: absolute;
      inset: calc(var(--gc-border-size) * -1);
      border: var(--gc-border-size) solid transparent;
      border-radius: calc(var(--gc-radius) * 1px);
      background-attachment: fixed;
      background-size: calc(100% + (2 * var(--gc-border-size))) calc(100% + (2 * var(--gc-border-size)));
      background-repeat: no-repeat;
      background-position: 50% 50%;
      -webkit-mask:
        linear-gradient(transparent, transparent),
        linear-gradient(white, white);
              mask:
        linear-gradient(transparent, transparent),
        linear-gradient(white, white);
      -webkit-mask-clip: padding-box, border-box;
              mask-clip: padding-box, border-box;
      -webkit-mask-composite: source-in, xor;
              mask-composite: intersect;
      z-index: 1;
    }
    [data-glow]::before {
      background-image: radial-gradient(
        calc(var(--gc-spotlight-size) * 0.75) calc(var(--gc-spotlight-size) * 0.75) at
        calc(var(--gc-x, 0) * 1px)
        calc(var(--gc-y, 0) * 1px),
        hsl(var(--gc-hue, 210) calc(var(--gc-saturation, 100) * 1%) calc(var(--gc-lightness, 50) * 1%) / var(--gc-border-spot-opacity, 1)),
        transparent 100%
      );
      filter: brightness(1.6);
    }
    [data-glow]::after {
      background-image: radial-gradient(
        calc(var(--gc-spotlight-size) * 0.5) calc(var(--gc-spotlight-size) * 0.5) at
        calc(var(--gc-x, 0) * 1px)
        calc(var(--gc-y, 0) * 1px),
        hsl(0 100% 100% / var(--gc-border-light-opacity, 0.85)),
        transparent 100%
      );
    }
    /* outer halo (blurred copy) */
    [data-glow] > [data-glow-halo] {
      position: absolute;
      inset: 0;
      will-change: filter;
      opacity: var(--gc-outer, 1);
      border-radius: calc(var(--gc-radius) * 1px);
      filter: blur(calc(var(--gc-border-size) * 8));
      background: none;
      pointer-events: none;
      border: none;
      z-index: 0;
    }
    [data-glow] > [data-glow-halo]::before {
      content: "";
      position: absolute;
      inset: -10px;
      border: 10px solid transparent;
      border-radius: inherit;
      background-image: radial-gradient(
        calc(var(--gc-spotlight-size) * 0.9) calc(var(--gc-spotlight-size) * 0.9) at
        calc(var(--gc-x, 0) * 1px)
        calc(var(--gc-y, 0) * 1px),
        hsl(var(--gc-hue, 210) calc(var(--gc-saturation, 100) * 1%) calc(var(--gc-lightness, 60) * 1%) / 0.9),
        transparent 70%
      );
      background-attachment: fixed;
      -webkit-mask:
        linear-gradient(transparent, transparent),
        linear-gradient(white, white);
              mask:
        linear-gradient(transparent, transparent),
        linear-gradient(white, white);
      -webkit-mask-clip: padding-box, border-box;
              mask-clip: padding-box, border-box;
      -webkit-mask-composite: source-in, xor;
              mask-composite: intersect;
    }

    [data-theme="light"] [data-glow]::before { filter: brightness(1.2); }
  `;
  const tag = document.createElement("style");
  tag.id = "glowcard-styles";
  tag.textContent = css;
  document.head.appendChild(tag);
}

// One global pointermove listener — efficient, fires once per move regardless of GlowCard count
let __gcPointerListenerSet = false;
const __gcCards = new Set();
function ensurePointerListener() {
  if (__gcPointerListenerSet || typeof window === "undefined") return;
  __gcPointerListenerSet = true;
  const onMove = (e) => {
    const x = e.clientX;
    const y = e.clientY;
    const xp = (x / window.innerWidth).toFixed(3);
    const yp = (y / window.innerHeight).toFixed(3);
    __gcCards.forEach((el) => {
      if (!el || !el.isConnected) return;
      el.style.setProperty("--gc-x", x.toFixed(2));
      el.style.setProperty("--gc-y", y.toFixed(2));
      el.style.setProperty("--gc-xp", xp);
      el.style.setProperty("--gc-yp", yp);
    });
  };
  document.addEventListener("pointermove", onMove, { passive: true });
}

function GlowCard({
  children,
  className = "",
  glowColor = "blue",
  radius = 16,
  border = 2,
  spotlightSize = 220,
  saturation = 100,
  lightness = 55,
  bgSpotOpacity = 0.12,
  borderSpotOpacity = 0.95,
  borderLightOpacity = 0.85,
  outer = 0.85,
  // visual chrome — pass false to not draw any background fill (fully transparent card)
  fill = true,
  as: Tag = "div",
  style: extraStyle,
  ...rest
}) {
  const ref = gcUseRef(null);
  const { base, spread } = GLOW_COLOR_MAP[glowColor] || GLOW_COLOR_MAP.blue;

  gcUseEffect(() => {
    injectGlowStyles();
    ensurePointerListener();
    const el = ref.current;
    if (el) __gcCards.add(el);
    return () => { if (el) __gcCards.delete(el); };
  }, []);

  const style = {
    "--gc-base":         base,
    "--gc-spread":       spread,
    "--gc-radius":       radius,
    "--gc-border":       border,
    "--gc-border-size":  `calc(var(--gc-border) * 1px)`,
    "--gc-spotlight-size": `calc(${spotlightSize} * 1px)`,
    "--gc-saturation":   saturation,
    "--gc-lightness":    lightness,
    "--gc-bg-spot-opacity":     bgSpotOpacity,
    "--gc-border-spot-opacity": borderSpotOpacity,
    "--gc-border-light-opacity": borderLightOpacity,
    "--gc-outer":        outer,
    "--gc-hue":          "calc(var(--gc-base) + (var(--gc-xp, 0) * var(--gc-spread, 0)))",
    backgroundImage: fill ? `radial-gradient(
        var(--gc-spotlight-size) var(--gc-spotlight-size) at
        calc(var(--gc-x, 0) * 1px)
        calc(var(--gc-y, 0) * 1px),
        hsl(var(--gc-hue, 210) calc(var(--gc-saturation, 100) * 1%) calc(var(--gc-lightness, 70) * 1%) / var(--gc-bg-spot-opacity, 0.1)),
        transparent
      )` : undefined,
    backgroundSize: "calc(100% + (2 * var(--gc-border-size))) calc(100% + (2 * var(--gc-border-size)))",
    backgroundPosition: "50% 50%",
    backgroundAttachment: "fixed",
    borderRadius: `calc(var(--gc-radius) * 1px)`,
    ...extraStyle,
  };

  return (
    <Tag ref={ref} data-glow="" className={"glow-card " + className} style={style} {...rest}>
      <div data-glow-halo="" aria-hidden="true" />
      {children}
    </Tag>
  );
}

window.GlowCard = GlowCard;
