/* global React */
const { useState, useEffect, useRef } = React;

// ===== Animation hooks ==================================================
function useInView(opts = { threshold: 0.20, rootMargin: "0px 0px -40px 0px" }) {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current || inView) return;
    // Fallback: if IO never fires (some embedded iframes), reveal anyway.
    const fallback = setTimeout(() => setInView(true), 350);

    if (typeof IntersectionObserver === "undefined") {
      setInView(true);
      return () => clearTimeout(fallback);
    }
    const el = ref.current;
    // Eager check: if element is already in viewport at mount, reveal immediately.
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh && rect.bottom > 0) {
      setInView(true);
      clearTimeout(fallback);
      return;
    }
    const io = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setInView(true);
          io.disconnect();
          clearTimeout(fallback);
        }
      },
      opts
    );
    io.observe(el);
    return () => { io.disconnect(); clearTimeout(fallback); };
  }, [inView]);
  return [ref, inView];
}

function useCountUp(end, { active = true, duration = 1800, decimals = 0 } = {}) {
  const [value, setValue] = useState(0);
  useEffect(() => {
    if (!active) return;
    let raf, t0;
    const tick = (t) => {
      if (!t0) t0 = t;
      const p = Math.min((t - t0) / duration, 1);
      const eased = 1 - Math.pow(1 - p, 4);
      setValue(end * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [end, active, duration]);
  const factor = Math.pow(10, decimals);
  return Math.round(value * factor) / factor;
}

function formatThousands(n) {
  return n.toLocaleString("en-US");
}

// ===== Reveal — passthrough wrapper ======================================
// (Originally a fade-up animation; environment-frozen CSS animations made
// the gating risky, so it now renders children directly with no styling.)
function Reveal({ children, as = "div", className = "" }) {
  const Tag = as;
  return <Tag className={className}>{children}</Tag>;
}

// ===== Halo background orbs ==============================================
function Halo({ children, variant = "default" }) {
  return (
    <div className={`halo-wrap halo-scoped halo--${variant}`}>
      <div className="halo halo-a" />
      <div className="halo halo-b" />
      <div className="halo-content">{children}</div>
    </div>
  );
}

// ===== Eyebrow ===========================================================
function Eyebrow({ children, icon = "sparkles" }) {
  return (
    <span className="eyebrow">
      {icon && <Icon name={icon} size={12} />}
      {children}
    </span>
  );
}

// ===== Section header ====================================================
function SectionHeader({ eyebrow, eyebrowIcon, title, subtitle, align = "left" }) {
  return (
    <header className={`section-header section-header--${align}`}>
      {eyebrow && <Eyebrow icon={eyebrowIcon}>{eyebrow}</Eyebrow>}
      <h2 className="section-title" dangerouslySetInnerHTML={{ __html: title }} />
      {subtitle && <p className="section-sub">{subtitle}</p>}
    </header>
  );
}

// ===== Section wrapper ===================================================
function Section({ id, children, className = "" }) {
  return (
    <section id={id} className={`section ${className}`}>
      <div className="container">{children}</div>
    </section>
  );
}

// ===== Button ============================================================
function Button({ variant = "primary", children, onClick, as = "button", href, icon, arrow, size }) {
  const cls = `btn btn--${variant}${size ? " btn--" + size : ""}`;
  const inner = (
    <>
      {children}
      {arrow && <span className="btn-arrow"><Icon name="arrow-right" size={16} /></span>}
      {icon && <span className="btn-icon">{icon}</span>}
    </>
  );
  if (as === "a") return <a className={cls} href={href} onClick={onClick} target={href && href.startsWith("http") ? "_blank" : undefined} rel={href && href.startsWith("http") ? "noopener noreferrer" : undefined}>{inner}</a>;
  return <button className={cls} onClick={onClick}>{inner}</button>;
}

// ===== Lucide icon (auto re-renders) =====================================
function Icon({ name, size = 20, color, strokeWidth = 2 }) {
  React.useEffect(() => {
    if (window.lucide) window.lucide.createIcons();
  });
  const style = { width: size, height: size, color };
  return <i data-lucide={name} style={style} data-stroke-width={strokeWidth} />;
}

Object.assign(window, {
  useInView, useCountUp, formatThousands,
  Reveal, Halo, Eyebrow, SectionHeader, Section, Button, Icon
});
