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

/* ─── Icons (Lucide-style, 1.5 stroke) ──────────────────────── */
function Icon({ name, size = 20, ...props }) {
  const stroke = props.stroke || 'currentColor';
  const sw = 1.5;
  const common = {
    width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
    stroke, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round',
    'aria-hidden': true, ...props
  };
  switch (name) {
    case 'arrow-right':   return <svg {...common}><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
    case 'arrow-up-right':return <svg {...common}><path d="M7 17 17 7M8 7h9v9"/></svg>;
    case 'check':         return <svg {...common}><path d="M20 6 9 17l-5-5"/></svg>;
    case 'sparkle':       return <svg {...common}><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>;
    case 'phone':         return <svg {...common}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.7 2.8a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.33 1.84.57 2.8.7A2 2 0 0 1 22 16.92Z"/></svg>;
    case 'mic':           return <svg {...common}><rect x="9" y="2" width="6" height="11" rx="3"/><path d="M19 10v1a7 7 0 0 1-14 0v-1M12 18v3"/></svg>;
    case 'volume':        return <svg {...common}><path d="M11 5 6 9H2v6h4l5 4V5zM15.54 8.46a5 5 0 0 1 0 7.07M19.07 4.93a10 10 0 0 1 0 14.14"/></svg>;
    case 'phone-off':     return <svg {...common}><path d="M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.33 1.84.57 2.8.7A2 2 0 0 1 22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07M5 5l-1 1a2 2 0 0 0-.5 1.72c.13.96.37 1.9.7 2.8M2 2l20 20"/></svg>;
    case 'play':          return <svg {...common}><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg>;
    case 'star':          return <svg {...common} fill="currentColor" stroke="none"><polygon points="12 2 15.1 8.4 22 9.3 17 14.1 18.2 21 12 17.7 5.8 21 7 14.1 2 9.3 8.9 8.4 12 2"/></svg>;
    case 'shield':        return <svg {...common}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>;
    case 'zap':           return <svg {...common}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>;
    case 'target':        return <svg {...common}><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>;
    case 'brain':         return <svg {...common}><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24A2.5 2.5 0 0 1 9.5 2zM14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24A2.5 2.5 0 0 0 14.5 2z"/></svg>;
    case 'trending':      return <svg {...common}><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>;
    case 'clock':         return <svg {...common}><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>;
    case 'x':             return <svg {...common}><path d="M18 4l-6 8 6 8h-3l-6-8 6-8zM6 4h3l6 16h-3z" fill="currentColor" stroke="none"/></svg>;
    case 'instagram':     return <svg {...common}><rect x="2" y="2" width="20" height="20" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"/></svg>;
    case 'linkedin':      return <svg {...common}><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-4 0v7h-4v-12h4v2a4 4 0 0 1 2-2zM6 9H2v12h4z"/><circle cx="4" cy="4" r="2"/></svg>;
    case 'menu':          return <svg {...common}><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>;
    default: return null;
  }
}

/* ─── Reveal-on-scroll hook ──────────────────────────────────── */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => {
        if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); }
      }),
      { threshold: 0.10, rootMargin: '0px 0px -32px 0px' }
    );
    el.querySelectorAll('.reveal').forEach((n) => io.observe(n));
    return () => io.disconnect();
  }, []);
  return ref;
}

/* ─── Logo ───────────────────────────────────────────────────── */
function Logo() {
  return (
    <a href="#" className="logo" aria-label="ColdCallable home">
      <img src="/assets/logo/Logo_Icon.svg" alt="" className="logo-mark" aria-hidden="true" width="32" height="32" />
      <img src="/assets/logo/Logo.svg" alt="ColdCallable" className="logo-wordmark" height="20" />
    </a>
  );
}

/* ─── EmailCapture ───────────────────────────────────────────── */
function EmailCapture({ dark = false, placeholder = 'your@email.com', cta = 'Join Waitlist' }) {
  const [email, setEmail] = useState('');
  const [state, setState] = useState('idle'); // idle | loading | done | error

  const validate = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);

  const submit = (e) => {
    e.preventDefault();
    if (!validate(email)) { setState('error'); return; }
    setState('loading');
    fetch('https://submit-form.com/v3DI3knqX', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
      body: JSON.stringify({ email }),
    })
      .then((r) => { if (!r.ok) throw new Error(); setState('done'); })
      .catch(() => setState('error'));
  };

  return (
    <form
      className={'email-capture' + (dark ? ' email-capture-dark' : '')}
      onSubmit={submit}
      aria-label="Waitlist email signup"
      noValidate
    >
      {state === 'done' ? (
        <div className="success-state" role="status">
          <Icon name="check" size={20} />
          <span>You're on the list. We'll be in touch.</span>
        </div>
      ) : (
        <>
          <label htmlFor={'email-' + cta.replace(/\s/g,'-')} className="sr-only">Email address</label>
          <input
            type="email"
            id={'email-' + cta.replace(/\s/g,'-')}
            inputMode="email"
            autoComplete="email"
            placeholder={state === 'error' ? "That email looks off — mind double-checking?" : placeholder}
            value={email}
            onChange={(e) => { setEmail(e.target.value); if (state === 'error') setState('idle'); }}
            aria-invalid={state === 'error'}
          />
          <button type="submit" disabled={state === 'loading'} aria-label={cta}>
            {state === 'loading' ? 'Saving…' : cta}
            {state !== 'loading' && <Icon name="arrow-right" size={16} />}
          </button>
        </>
      )}
    </form>
  );
}

/* ─── CountUp ────────────────────────────────────────────────── */
function CountUp({ to, suffix = '', duration = 1600 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let started = false;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          const start = performance.now();
          const tick = (now) => {
            const t = Math.min(1, (now - start) / duration);
            const eased = 1 - Math.pow(1 - t, 3);
            setVal(Math.floor(eased * to));
            if (t < 1) requestAnimationFrame(tick); else setVal(to);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{val.toLocaleString()}{suffix}</span>;
}

Object.assign(window, { Icon, useReveal, Logo, EmailCapture, CountUp });
