// effects.jsx — Inline implementations of signature effects from
// aceternity-ui, magicui, reactbits, and shadcn patterns.
// Standalone — no Tailwind required.

// ── Animated beam border (MagicUI-style) ────────────────────────────────
function BeamBorder({ children, color = '#ffce3a', color2 = '#ff5a3c', radius = 6, duration = 4, thickness = 2, style }) {
  const id = React.useId();
  return (
    <div style={{
      position: 'relative',
      borderRadius: radius,
      padding: thickness,
      isolation: 'isolate',
      overflow: 'hidden',
      ...style,
    }}>
      <div style={{
        position: 'absolute', inset: 0,
        borderRadius: radius,
        background: `conic-gradient(from 0deg, transparent 0deg, ${color} 60deg, ${color2} 120deg, transparent 180deg, transparent 360deg)`,
        animation: `beam-spin-${id.replace(/:/g, '')} ${duration}s linear infinite`,
        zIndex: 0,
      }} />
      <style>{`
        @keyframes beam-spin-${id.replace(/:/g, '')} {
          to { transform: rotate(360deg); }
        }
      `}</style>
      <div style={{
        position: 'relative',
        borderRadius: radius - 1,
        background: 'var(--pd-bg-2)',
        zIndex: 1,
        height: '100%',
      }}>
        {children}
      </div>
    </div>
  );
}

// ── 3D mouse-tilt card (Aceternity-style) ───────────────────────────────
function TiltCard({ children, max = 8, scale = 1.02, style, className }) {
  const ref = React.useRef(null);
  const [tx, setTx] = React.useState({ rx: 0, ry: 0, s: 1 });

  function handleMove(e) {
    const r = ref.current.getBoundingClientRect();
    const cx = e.clientX - r.left - r.width / 2;
    const cy = e.clientY - r.top - r.height / 2;
    setTx({
      rx: (cy / r.height) * -max,
      ry: (cx / r.width) * max,
      s: scale,
    });
  }
  function handleLeave() { setTx({ rx: 0, ry: 0, s: 1 }); }

  return (
    <div
      ref={ref}
      onMouseMove={handleMove}
      onMouseLeave={handleLeave}
      className={className}
      style={{
        transform: `perspective(900px) rotateX(${tx.rx}deg) rotateY(${tx.ry}deg) scale(${tx.s})`,
        transition: 'transform .12s ease-out',
        transformStyle: 'preserve-3d',
        ...style,
      }}
    >
      {children}
    </div>
  );
}

// ── Spotlight (cursor-following radial glow) ────────────────────────────
function Spotlight({ color = 'rgba(255, 206, 58, .14)', size = 600 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    function move(e) {
      const r = el.getBoundingClientRect();
      el.style.setProperty('--mx', `${e.clientX - r.left}px`);
      el.style.setProperty('--my', `${e.clientY - r.top}px`);
    }
    const parent = el.parentElement;
    parent.addEventListener('pointermove', move);
    return () => parent.removeEventListener('pointermove', move);
  }, []);
  return (
    <div
      ref={ref}
      style={{
        position: 'absolute', inset: 0,
        pointerEvents: 'none',
        background: `radial-gradient(${size}px circle at var(--mx, 50%) var(--my, 50%), ${color}, transparent 60%)`,
        transition: 'background .2s',
        zIndex: 1,
      }}
    />
  );
}

// ── Sparkles / particle overlay ─────────────────────────────────────────
function Sparkles({ count = 28, color = '#ffce3a' }) {
  const dots = React.useMemo(() => Array.from({ length: count }, (_, i) => ({
    x: Math.random() * 100,
    y: Math.random() * 100,
    s: 1 + Math.random() * 2,
    d: 1 + Math.random() * 3,
    delay: Math.random() * 4,
    k: i,
  })), [count]);
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>
      {dots.map(d => (
        <span
          key={d.k}
          style={{
            position: 'absolute',
            left: `${d.x}%`, top: `${d.y}%`,
            width: d.s, height: d.s,
            background: color,
            borderRadius: '50%',
            boxShadow: `0 0 ${d.s * 3}px ${color}`,
            animation: `sparkle ${d.d + 2}s ease-in-out ${d.delay}s infinite`,
          }}
        />
      ))}
      <style>{`
        @keyframes sparkle {
          0%, 100% { opacity: 0; transform: scale(.5); }
          50%       { opacity: 1; transform: scale(1.5); }
        }
      `}</style>
    </div>
  );
}

// ── Animated counting number (count-up) ─────────────────────────────────
function AnimatedNumber({ value, decimals = 0, prefix = '', suffix = '', duration = 1200 }) {
  const [display, setDisplay] = React.useState(value);
  const start = React.useRef({ from: value, to: value, t0: 0 });
  React.useEffect(() => {
    start.current = { from: display, to: value, t0: performance.now() };
    let raf;
    const tick = (now) => {
      const { from, to, t0 } = start.current;
      const p = Math.min(1, (now - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setDisplay(from + (to - from) * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [value]);
  return (
    <span className="numroll">{prefix}{display.toFixed(decimals)}{suffix}</span>
  );
}

// ── Floating gradient orbs (background ambient) ─────────────────────────
function GradientOrbs({ orbs }) {
  const arr = orbs || [
    { color: '#e53935', size: 360, x: '12%', y: '20%', delay: 0 },
    { color: '#2746c3', size: 420, x: '78%', y: '60%', delay: 2 },
    { color: '#ffce3a', size: 280, x: '52%', y: '85%', delay: 4 },
  ];
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden' }}>
      {arr.map((o, i) => (
        <div key={i} style={{
          position: 'absolute',
          left: o.x, top: o.y,
          width: o.size, height: o.size,
          background: `radial-gradient(circle, ${o.color}, transparent 65%)`,
          opacity: .35,
          filter: 'blur(40px)',
          mixBlendMode: 'screen',
          transform: 'translate(-50%, -50%)',
          animation: `orb-drift 12s ease-in-out ${o.delay}s infinite alternate`,
        }} />
      ))}
      <style>{`
        @keyframes orb-drift {
          0%   { transform: translate(-50%, -50%) scale(1); }
          100% { transform: translate(-40%, -55%) scale(1.15); }
        }
      `}</style>
    </div>
  );
}

// ── Animated grid pattern (MagicUI-style) ───────────────────────────────
function AnimatedGrid({ color = 'rgba(255,206,58,.08)', size = 40, speed = 25 }) {
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden', zIndex: 0 }}>
      <div style={{
        position: 'absolute',
        inset: '-50%',
        background: `
          linear-gradient(${color} 1px, transparent 1px),
          linear-gradient(90deg, ${color} 1px, transparent 1px)
        `,
        backgroundSize: `${size}px ${size}px`,
        animation: `grid-pan ${speed}s linear infinite`,
        maskImage: 'radial-gradient(ellipse at center, black 30%, transparent 75%)',
        WebkitMaskImage: 'radial-gradient(ellipse at center, black 30%, transparent 75%)',
      }} />
      <style>{`
        @keyframes grid-pan {
          0% { transform: translate(0, 0); }
          100% { transform: translate(${size}px, ${size}px); }
        }
      `}</style>
    </div>
  );
}

// ── Scroll reveal: wraps children, animates in on entry ─────────────────
function Reveal({ children, delay = 0, y = 30, duration = 0.8 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el || !window.gsap) return;
    window.gsap.set(el, { opacity: 0, y });
    const trigger = window.ScrollTrigger?.create({
      trigger: el,
      start: 'top 85%',
      onEnter: () => {
        window.gsap.to(el, { opacity: 1, y: 0, duration, delay, ease: 'power3.out' });
      },
      once: true,
    });
    // If no scrolltrigger, just animate
    if (!window.ScrollTrigger) {
      window.gsap.to(el, { opacity: 1, y: 0, duration, delay, ease: 'power3.out' });
    }
    return () => trigger?.kill();
  }, []);
  return <div ref={ref}>{children}</div>;
}

// ── Hero entrance: stagger children on mount ────────────────────────────
function useHeroEntrance(selector) {
  React.useEffect(() => {
    if (!window.gsap) return;
    const els = document.querySelectorAll(selector);
    if (!els.length) return;
    window.gsap.from(els, {
      opacity: 0,
      y: 30,
      duration: 0.9,
      stagger: 0.08,
      ease: 'power3.out',
      delay: 0.1,
    });
  }, [selector]);
}

// ── Shimmer text (gradient passing through) ─────────────────────────────
function Shimmer({ children, color = '#ffce3a', from = '#fff' }) {
  return (
    <span style={{
      display: 'inline-block',
      background: `linear-gradient(110deg, ${from} 0%, ${from} 40%, ${color} 50%, ${from} 60%, ${from} 100%)`,
      backgroundSize: '300% 100%',
      WebkitBackgroundClip: 'text',
      backgroundClip: 'text',
      color: 'transparent',
      animation: 'shimmer 3.6s linear infinite',
    }}>
      {children}
      <style>{`@keyframes shimmer { 0%{background-position:200% 0;} 100%{background-position:-200% 0;} }`}</style>
    </span>
  );
}

// ── Magnetic button (cursor-pulls) ──────────────────────────────────────
function Magnetic({ children, strength = 0.25 }) {
  const ref = React.useRef(null);
  function move(e) {
    const el = ref.current;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - r.left - r.width / 2) * strength;
    const y = (e.clientY - r.top - r.height / 2) * strength;
    el.style.transform = `translate(${x}px, ${y}px)`;
  }
  function leave() { ref.current.style.transform = 'translate(0,0)'; }
  return (
    <span ref={ref} onMouseMove={move} onMouseLeave={leave}
      style={{ display: 'inline-block', transition: 'transform .2s cubic-bezier(.2,.8,.2,1)' }}>
      {children}
    </span>
  );
}

// ── Marquee (smooth, gsap-driven would be overkill — pure CSS) ──────────
// (already in styles.css as .ticker)

Object.assign(window, {
  BeamBorder, TiltCard, Spotlight, Sparkles, AnimatedNumber,
  GradientOrbs, AnimatedGrid, Reveal, useHeroEntrance, Shimmer, Magnetic,
});
