// Shared components for nthStudio landing page
const { useState, useEffect, useRef, useMemo } = React;

/* ─── Reveal: fade-up on scroll ─── */
function Reveal({ as = 'div', delay = 0, children, className = '', ...rest }) {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => {if (e.isIntersecting) {setInView(true);io.unobserve(el);}}),
      { threshold: 0.15, rootMargin: '0px 0px -60px 0px' }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return (
    <Tag
      ref={ref}
      className={`rv ${inView ? 'in' : ''} ${className}`}
      style={{ transitionDelay: `${delay}ms` }}
      {...rest}>
      
      {children}
    </Tag>);

}

/* ─── Type-on effect for the hero subhead ─── */
function TypeOn({ text, speed = 28, startDelay = 500, caret = true }) {
  const [out, setOut] = useState('');
  const [done, setDone] = useState(false);
  useEffect(() => {
    let i = 0;
    let t;
    const start = setTimeout(() => {
      const step = () => {
        i += 1;
        setOut(text.slice(0, i));
        if (i < text.length) t = setTimeout(step, speed);else
        setDone(true);
      };
      step();
    }, startDelay);
    return () => {clearTimeout(start);clearTimeout(t);};
  }, [text]);
  return (
    <span>
      {out}
      {caret && !done && <span className="caret" />}
    </span>);

}

/* ─── Count-up number (parses prefix/suffix around digits) ─── */
function CountUp({ value, duration = 1400, className = '' }) {
  // pull leading sign, a numeric block, and a trailing unit
  const m = String(value).match(/^([+\-−]?)([0-9]*\.?[0-9]+)(.*)$/);
  const ref = useRef(null);
  const [n, setN] = useState(0);
  const [started, setStarted] = useState(false);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {if (e.isIntersecting && !started) {setStarted(true);io.unobserve(el);}});
    }, { threshold: 0.3 });
    io.observe(el);
    return () => io.disconnect();
  }, [started]);

  useEffect(() => {
    if (!started || !m) return;
    const target = parseFloat(m[2]);
    const decimals = (m[2].split('.')[1] || '').length;
    const t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setN(+(target * eased).toFixed(decimals));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [started]);

  if (!m) return <span className={className}>{value}</span>;
  const decimals = (m[2].split('.')[1] || '').length;
  return (
    <span ref={ref} className={className}>
      {m[1]}{n.toFixed(decimals)}{m[3]}
    </span>);

}

/* ─── Button ─── */
function Btn({ variant = 'primary', href = '#', children, ...rest }) {
  return (
    <a href={href} className={`btn btn-${variant}`} {...rest}>
      {children} <span className="btn-arrow" style={{ letterSpacing: "1px", textAlign: "left", lineHeight: "1", fontSize: "14px", margin: "0px", padding: "0px", height: "14px", width: "14px" }} />
    </a>);

}

/* ─── FoldMeta — the thin label at the top of each section ─── */
function FoldMeta({ label, kicker, onColor }) {
  return (
    <Reveal className="fold-meta" style={onColor ? { color: onColor } : undefined}>
      <span className="mono">{label}</span>
      <span className="rule" />
      <span className="mono">{kicker}</span>
    </Reveal>);

}

/* ─── Wordmark — the nthStudio logo, one colour per segment ─── */
function Wordmark() {
  return (
    <span className="wordmark" aria-label="nthStudio">
      <span style={{ color: 'var(--brand-n)' }}>n</span>
      <span style={{ color: 'var(--brand-th)' }}>th</span>
      <span style={{ color: 'var(--brand-studio)' }}>Studio</span>
    </span>);

}

Object.assign(window, { Reveal, TypeOn, CountUp, Btn, FoldMeta, Wordmark });