// Skool community links (single source of truth for CTAs)
const PU_LINKS = {
  free: "https://www.skool.com/producerunion",
  plus: "https://www.skool.com/producer-union-plus",
};

function JoinCta({ href, children, variant = "primary", className = "", style = {}, sub, block }) {
  return (
    <a
      href={href}
      target="_blank"
      rel="noopener noreferrer"
      className={`btn join-cta btn-${variant}${block ? " join-cta-block" : ""} ${className}`.trim()}
      style={style}
    >
      <span className="join-cta-inner">
        <span className="join-cta-label">{children}</span>
        {sub ? <span className="join-cta-sub">{sub}</span> : null}
      </span>
      <Arrow />
    </a>
  );
}

window.PU_LINKS = PU_LINKS;
window.JoinCta = JoinCta;

// Shared helpers and tiny primitives.

function useInView(opts = {}) {
  const ref = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setInView(true);
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.15, ...opts }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, inView];
}

function Reveal({ children, delay = 0, className = "", as: As = "div", style }) {
  const [ref, inView] = useInView();
  return (
    <As
      ref={ref}
      className={`reveal ${inView ? "in" : ""} ${className}`}
      style={{ transitionDelay: `${delay}ms`, ...style }}>
      
      {children}
    </As>);

}

// Animated counter that ticks from `from` to `to` once it enters view.
function useCountUp(target, { duration = 1400, decimals = 0, suffix = "", prefix = "" } = {}) {
  const [value, setValue] = React.useState(0);
  const [ref, inView] = useInView();
  React.useEffect(() => {
    if (!inView) return;
    let raf;
    const start = performance.now();
    const animate = (now) => {
      const t = Math.min(1, (now - start) / duration);
      // ease out cubic
      const e = 1 - Math.pow(1 - t, 3);
      setValue(target * e);
      if (t < 1) raf = requestAnimationFrame(animate);
    };
    raf = requestAnimationFrame(animate);
    return () => cancelAnimationFrame(raf);
  }, [inView, target, duration]);
  const display = prefix + value.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ",") + suffix;
  return [display, ref];
}

function CountUp({ to, decimals = 0, prefix = "", suffix = "", duration = 1400, className = "" }) {
  const [display, ref] = useCountUp(to, { decimals, prefix, suffix, duration });
  return (
    <span ref={ref} className={`tight-num ${className}`} style={{ fontSize: "100px" }}>
      {display}
    </span>);

}

// Smoothly animate from previous value to new value (for calculator).
function useSmooth(target, ms = 400) {
  const [val, setVal] = React.useState(target);
  const fromRef = React.useRef(target);
  React.useEffect(() => {
    const from = fromRef.current;
    const start = performance.now();
    let raf;
    const tick = (now) => {
      const t = Math.min(1, (now - start) / ms);
      const e = 1 - Math.pow(1 - t, 3);
      const v = from + (target - from) * e;
      setVal(v);
      if (t < 1) raf = requestAnimationFrame(tick);else
      fromRef.current = target;
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, ms]);
  return val;
}

function formatMoney(n) {
  return "$" + Math.round(n).toLocaleString("en-US");
}
function formatNum(n) {
  return Math.round(n).toLocaleString("en-US");
}

// Tiny arrow glyph
const Arrow = ({ d = "right", className = "" }) => {
  const rotations = { right: 0, left: 180, up: -90, down: 90, "down-right": 45 };
  return (
    <svg className={className} width="14" height="14" viewBox="0 0 14 14" fill="none"
    style={{ transform: `rotate(${rotations[d]}deg)`, transition: "transform 0.18s ease" }}>
      <path d="M2 7H12M12 7L7 2M12 7L7 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
    </svg>);

};

// Reusable Liquid-Glass segmented control with a sliding frosted pill.
// items: [{ id, label, num?, sub?, color? }]  — color sets the active accent (--seg-accent).
function GlassSegmented({ items, active, onChange, ariaLabel, full = false, variant, className = "" }) {
  const trackRef = React.useRef(null);
  const itemRefs = React.useRef([]);
  const [pillStyle, setPillStyle] = React.useState({ transform: "translateX(0px)", width: "0px" });
  const [ready, setReady] = React.useState(false);

  const activeIndex = Math.max(0, items.findIndex((it) => it.id === active));
  const activeColor = items[activeIndex] && items[activeIndex].color;

  // Measure the active item synchronously before paint so the pill never flashes off-position.
  const measure = React.useCallback(() => {
    const el = itemRefs.current[activeIndex];
    const track = trackRef.current;
    if (!el || !track) return;
    setPillStyle({ transform: `translateX(${el.offsetLeft}px)`, width: `${el.offsetWidth}px` });
  }, [activeIndex]);

  React.useLayoutEffect(() => {
    measure();
    // Enable the spring only after the first measure, so the pill snaps on mount instead of sliding from 0.
    if (!ready) {
      const r = requestAnimationFrame(() => requestAnimationFrame(() => setReady(true)));
      return () => cancelAnimationFrame(r);
    }
  }, [measure, ready]);

  // Re-glue after viewport changes and after webfonts load (pill width depends on font metrics).
  React.useLayoutEffect(() => {
    window.addEventListener("resize", measure);
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(measure);
    return () => window.removeEventListener("resize", measure);
  }, [measure]);

  const pillCss = activeColor ? { ...pillStyle, "--seg-accent": activeColor } : pillStyle;

  return (
    <div
      className={`glass-seg ${full ? "glass-seg-full" : ""} ${variant ? "glass-seg-" + variant : ""} ${className}`.trim()}
      ref={trackRef}
      data-ready={ready ? "" : undefined}
      role="tablist"
      aria-label={ariaLabel}
    >
      <div className="glass-seg-pill" aria-hidden="true" style={pillCss} />
      {items.map((it, i) => {
        const isActive = it.id === active;
        return (
          <button
            key={it.id}
            ref={(node) => { itemRefs.current[i] = node; }}
            onClick={() => onChange(it.id)}
            role="tab"
            aria-selected={isActive ? "true" : "false"}
            className={`glass-seg-item ${isActive ? "active" : ""}`}
            style={it.color ? { "--seg-accent": it.color } : undefined}
          >
            <span className="glass-seg-item-top">
              {it.num ? <span className="glass-seg-item-num">{it.num}</span> : null}
              <span className="glass-seg-item-label">{it.label}</span>
            </span>
            {it.sub ? <span className="glass-seg-item-sub">{it.sub}</span> : null}
          </button>
        );
      })}
    </div>
  );
}
window.GlassSegmented = GlassSegmented;

Object.assign(window, { useInView, Reveal, useCountUp, CountUp, useSmooth, formatMoney, formatNum, Arrow, GlassSegmented });