const prefersReducedMotion = () => window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const MOTION_KEY = 'aq-motion';
function readMotionPaused() { try { return localStorage.getItem(MOTION_KEY) === 'paused'; } catch (e) { return false; } }
document.documentElement.dataset.motion = readMotionPaused() ? 'paused' : 'running';

function setMotionPaused(paused) {
  document.documentElement.dataset.motion = paused ? 'paused' : 'running';
  try { localStorage.setItem(MOTION_KEY, paused ? 'paused' : 'running'); } catch (e) {}
  window.dispatchEvent(new CustomEvent('aq-motion', { detail: paused }));
}

function useMotionPaused() {
  const [paused, setPaused] = React.useState(() => document.documentElement.dataset.motion === 'paused');
  React.useEffect(() => {
    const onChange = e => setPaused(e.detail);
    window.addEventListener('aq-motion', onChange);
    return () => window.removeEventListener('aq-motion', onChange);
  }, []);
  return paused;
}

function useDocumentVisible() {
  const [visible, setVisible] = React.useState(() => document.visibilityState !== 'hidden');
  React.useEffect(() => {
    const onChange = () => setVisible(document.visibilityState !== 'hidden');
    document.addEventListener('visibilitychange', onChange);
    return () => document.removeEventListener('visibilitychange', onChange);
  }, []);
  return visible;
}

function useScrollFade(ref) {
  const [fade, setFade] = React.useState('none');
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const update = () => {
      const max = el.scrollWidth - el.clientWidth;
      if (max <= 2) { setFade('none'); return; }
      const atStart = el.scrollLeft <= 2, atEnd = el.scrollLeft >= max - 2;
      setFade(atStart ? 'end' : atEnd ? 'start' : 'both');
    };
    update();
    el.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    return () => { el.removeEventListener('scroll', update); window.removeEventListener('resize', update); };
  }, []);
  return fade;
}

function useInView(ref, { once = true, rootMargin = '0px 0px -10% 0px' } = {}) {
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!('IntersectionObserver' in window) || prefersReducedMotion()) { setInView(true); return; }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); if (once) io.disconnect(); }
      else if (!once) setInView(false);
    }, { rootMargin, threshold: 0 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return inView;
}

function Reveal({ as: Tag = 'div', delay = 0, variant, className = '', style, children, ...rest }) {
  const ref = React.useRef(null);
  const inView = useInView(ref);
  const cls = ['rv', variant && 'rv--' + variant, inView && 'in', className].filter(Boolean).join(' ');
  return <Tag ref={ref} className={cls} style={{ '--rv': delay + 'ms', ...style }} {...rest}>{children}</Tag>;
}

function routeLink(go, route, intent) {
  return {
    href: '#' + route,
    onClick: e => {
      if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
      e.preventDefault();
      go(route, intent);
    },
  };
}

function Cta({ children, variant, size, icon = 'arrow-up-right', noIcon, full, onClick, href, disabled, type = 'button', style, className = '', ...rest }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  const motion = icon === 'plus' ? 's-btn--plus' : icon === 'arrow-up-right' ? 's-btn--go' : icon === 'arrow-down' ? 's-btn--down' : 's-btn--nudge';
  const cls = ['s-btn', variant && 's-btn--' + variant, size && 's-btn--' + size, noIcon ? 's-btn--noi' : motion, full && 's-btn--full', className].filter(Boolean).join(' ');
  const inner = <>{children}{!noIcon && <span className="s-btn-i" aria-hidden="true"><Icon name={icon} size={size === 'sm' ? 16 : 18} stroke={2.2} /></span>}</>;
  if (href) return <a className={cls} href={href} onClick={onClick} style={style} {...rest}>{inner}</a>;
  return <button type={type} className={cls} onClick={onClick} disabled={disabled} style={style} {...rest}>{inner}</button>;
}

function Pill({ children, onBrand, dot }) {
  return <span className={'s-pill' + (onBrand ? ' s-pill--on-brand' : '')}>{dot && <i className="s-pill-dot" />}{children}</span>;
}

function Badge({ tone = 'success', icon, children }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  return <span className={'s-badge s-badge--' + tone}>{icon && <Icon name={icon} size={13} stroke={2.6} />}{children}</span>;
}

function Tag({ icon, tone, children }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  return <span className={'s-tag' + (tone ? ' s-tag--' + tone : '')}>{icon && <Icon name={icon} size={15} />}{children}</span>;
}

function Stat({ value, prefix = '', suffix = '', label, size = 'md', onBrand, className = '' }) {
  const numeric = typeof value === 'number';
  return <div className={'s-stat' + (onBrand ? ' s-stat--on-brand' : '') + (className ? ' ' + className : '')}>
    <div className={'s-num s-num--' + size}>{numeric ? <Counter value={value} prefix={prefix} suffix={suffix} /> : prefix + value + suffix}</div>
    {label && <div className="s-stat-label">{label}</div>}
  </div>;
}

function Disclosure({ title, children, open, onToggle, compact }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  const id = React.useId();
  return <div className={'disc' + (compact ? ' disc--compact' : '') + (open ? ' open' : '')}>
    <button type="button" className="disc-btn" aria-expanded={open} aria-controls={id} onClick={onToggle}>
      <span className="disc-title">{title}</span>
      <span className="s-toggle" aria-hidden="true"><Icon name="plus" size={16} stroke={2.4} /></span>
    </button>
    <div className="acc" id={id}><div><div className="disc-body">{children}</div></div></div>
  </div>;
}

function SectionHead({ tag, title, lead, left, onBrand, children, titleClass = 's-h2' }) {
  return <div className={'s-head' + (left ? ' s-head--left' : '') + (onBrand ? ' s-on-brand' : '')}>
    {tag && <Reveal><Pill onBrand={onBrand}>{tag}</Pill></Reveal>}
    <Reveal as="h2" delay={80} className={'s-display ' + titleClass}>{title}</Reveal>
    {lead && <Reveal as="p" delay={160} className="s-lead">{lead}</Reveal>}
    {children && <Reveal delay={240}>{children}</Reveal>}
  </div>;
}

function Counter({ value, prefix = '', suffix = '', duration = 1600 }) {
  const ref = React.useRef(null);
  const inView = useInView(ref);
  const [n, setN] = React.useState(0);
  React.useEffect(() => {
    if (!inView) return;
    if (prefersReducedMotion()) { setN(value); return; }
    let raf = 0;
    const t0 = performance.now();
    const tick = t => {
      const p = Math.min(1, (t - t0) / duration);
      setN(Math.round(value * (1 - Math.pow(1 - p, 4))));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [inView, value, duration]);
  return <span ref={ref}>{prefix}{n.toLocaleString('en-IN')}{suffix}</span>;
}

function Barcode({ value }) {
  const { bars, width } = React.useMemo(() => {
    const out = [];
    let x = 0;
    for (const ch of value) {
      const c = ch.charCodeAt(0);
      for (let k = 0; k < 4; k++) {
        const w = 1 + ((c >> k) & 1) + ((c >> (k + 2)) & 1);
        if (k % 2 === 0) out.push([x, w]);
        x += w + 1;
      }
    }
    return { bars: out, width: x };
  }, [value]);
  return <svg className="pp-barcode" viewBox={'0 0 ' + width + ' 10'} preserveAspectRatio="none" aria-hidden="true">{bars.map(([x, w], i) => <rect key={i} x={x} y="0" width={w} height="10" />)}</svg>;
}

function Stamp({ children, sub, round, rotate = -8, delay = 0, className = '', style }) {
  return <span className={'stamp' + (round ? ' stamp--round' : '') + (className ? ' ' + className : '')} style={{ '--rot': rotate + 'deg', '--dl': delay + 'ms', ...style }} aria-hidden="true">
    <b>{children}</b>{sub && <small>{sub}</small>}
  </span>;
}

function Passport({ kicker = 'Can passport', id, size = '20 L', big, bigLabel, rows = [], stamp, note = 'Example can', label, className = '', style, delay = 0 }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  const ref = React.useRef(null);
  const play = useInView(ref);
  return <div ref={ref} className={'pp' + (play ? ' pp--play' : '') + (className ? ' ' + className : '')} style={style} role="group" aria-label={label || kicker + ' ' + id}>
    <span className="pp-hole" aria-hidden="true" />
    <div className="pp-head">
      <div className="pp-kicker">{kicker}</div>
      <div className="pp-id"><span>{id}</span><span>{size}</span></div>
      <Barcode value={id} />
    </div>
    {big != null && <div className="pp-big">
      <span className="pp-big-n">{typeof big === 'number' ? <Counter value={big} /> : big}</span>
      <span className="pp-big-l">{bigLabel}</span>
      {stamp}
    </div>}
    <div className="pp-perf" aria-hidden="true" />
    <ol className="pp-rows">
      {rows.map((r, i) => <li key={i} className={'pp-row' + (r.current ? ' pp-row--now' : '')} style={{ '--dl': delay + 200 + i * 160 + 'ms' }}>
        <span className="pp-time">{r.time}</span>
        <span className="pp-event">{r.label}{r.place && <small>{r.place}</small>}</span>
        <span className="pp-mark">{r.done ? <Icon name="check" size={16} stroke={2.6} /> : r.current ? <i className="pp-live" /> : null}</span>
      </li>)}
    </ol>
    {big == null && stamp}
    {note && <div className="pp-note">{note}</div>}
  </div>;
}

function PageHero({ tag, title, lead, actions, media, center, meta, children }) {
  return <section className="ph">
    <div className="ph-card">
      {meta && <div className="s-meta hx-rise" style={{ '--dl': '.05s' }}>{meta.map((m, i) => <span key={i}>{i === 0 && <i />}{m}</span>)}</div>}
      <div className={'ph-in' + (center ? ' ph-in--center' : '')}>
        <div>
          {tag && <div className="hx-rise" style={{ '--dl': '.15s' }}><Pill dot>{tag}</Pill></div>}
          <h1 className="ph-title"><span className="hx-ln"><span style={{ '--dl': '.3s' }}>{title}</span></span></h1>
          {lead && <p className="ph-lead hx-rise" style={{ '--dl': '.55s' }}>{lead}</p>}
          {actions && <div className="s-actions hx-rise" style={{ '--dl': '.7s' }}>{actions}</div>}
          {children}
        </div>
        {media && <div className="ph-media hx-rise" style={{ '--dl': '.5s' }}>{media}</div>}
      </div>
    </div>
  </section>;
}

function Segmented({ items, value, onChange, label }) {
  const ref = React.useRef(null);
  const fade = useScrollFade(ref);
  return <div ref={ref} className="seg" data-fade={fade} role="group" aria-label={label}>
    {items.map(it => <button type="button" key={it.value} aria-pressed={it.value === value} className={it.value === value ? 'on' : ''} onClick={() => onChange(it.value)}>{it.label}</button>)}
  </div>;
}

function FaqGrid({ items, columns = 2, defaultOpen = -1 }) {
  const [open, setOpen] = React.useState(() => new Set(defaultOpen >= 0 ? [defaultOpen] : []));
  const toggle = i => setOpen(s => { const n = new Set(s); n.has(i) ? n.delete(i) : n.add(i); return n; });
  const cols = Array.from({ length: columns }, (_, c) => items.map((it, i) => [it, i]).filter(([, i]) => i % columns === c));
  return <div className={columns > 1 ? 'g2' : ''} style={{ alignItems: 'start', display: 'grid', gap: 12 }}>
    {cols.map((col, c) => <div key={c} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      {col.map(([it, i]) => <Reveal key={it.q} delay={(i % 4) * 60}>
        <Disclosure title={it.q} open={open.has(i)} onToggle={() => toggle(i)}><p>{it.a}</p></Disclosure>
      </Reveal>)}
    </div>)}
  </div>;
}

function PlanTile({ name, price, period, note, features, cta, action, selected, featured, badge, icon = 'plus', selectable, onSelect }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  return <div className={'pt' + (featured ? ' pt--feat' : '') + (selected ? ' sel' : '') + (selectable ? ' pt--selectable' : '')} onClick={selectable ? onSelect : undefined}>
    <div className="pt-top">
      <div className="pt-name">{name}{selectable && selected ? <Badge tone={featured ? 'light' : 'info'} icon="check">Selected</Badge> : badge && <Badge tone={featured ? 'light' : 'info'}>{badge}</Badge>}</div>
      <div className="pt-price">{price}<small>{period}</small></div>
      <p className="pt-note">{note}</p>
    </div>
    <div className="pt-perf" aria-hidden="true" />
    <ul className="pt-feats">{features.map(f => <li key={f}><Icon name="check" size={18} stroke={2.4} />{f}</li>)}</ul>
    <Cta full variant={featured ? 'light' : undefined} icon={selected ? 'check' : icon} {...action}>{cta}</Cta>
  </div>;
}

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

function AreaCheck() {
  const { AreaChecker, Input, Icon } = window.DesignSystem_f6a2e7;
  const [missed, setMissed] = React.useState(false);
  const [email, setEmail] = React.useState('');
  const [error, setError] = React.useState();
  const [saved, setSaved] = React.useState('');
  const onResult = r => { setMissed(!!r && !r.ok); setSaved(''); setError(undefined); };
  const notify = e => {
    e.preventDefault();
    const v = email.trim();
    if (!EMAIL_RE.test(v)) { setError(v ? "That email doesn't look right." : 'Add your email so we can tell you.'); return; }
    setSaved(v);
    setEmail('');
  };
  return <div className="area-check">
    <AreaChecker compact onResult={onResult} />
    {missed && !saved && <form className="area-notify" onSubmit={notify} noValidate>
      <Input label="Email me when you deliver here" type="email" icon="mail" placeholder="you@example.com" value={email} onChange={e => { setEmail(e.target.value); setError(undefined); }} error={error} />
      <div><Cta type="submit" size="sm" icon="send">Notify me</Cta></div>
    </form>}
    {saved && <p className="area-saved" role="status"><Icon name="check-circle-2" size={18} />We'll email {saved} when our routes reach you.</p>}
  </div>;
}

function ImageCard({ img, alt, tag, title, href, onClick }) {
  const { Icon } = window.DesignSystem_f6a2e7;
  return <a className="ic" href={href} onClick={onClick}>
    <div className="ic-img"><img src={img} alt={alt} loading="lazy" /></div>
    <div className="ic-body">
      <div>{tag && <Pill>{tag}</Pill>}<div className="s-h3" style={{ marginTop: 14 }}>{title}</div></div>
      <span className="s-icon-btn s-icon-btn--white" aria-hidden="true"><Icon name="arrow-up-right" size={20} stroke={2} /></span>
    </div>
  </a>;
}

function StatTile({ value, prefix, suffix, label, brand, delay }) {
  return <Reveal delay={delay} className={'s-card stat' + (brand ? ' s-card--brand' : '')}>
    <Stat size="lg" onBrand={brand} value={value} prefix={prefix} suffix={suffix} label={label} />
  </Reveal>;
}

Object.assign(window, { EMAIL_RE, AreaCheck, setMotionPaused, useMotionPaused, useDocumentVisible, useScrollFade, prefersReducedMotion, useInView, Reveal, routeLink, Cta, Pill, Badge, Tag, Stat, Disclosure, SectionHead, Counter, Barcode, Stamp, Passport, PageHero, Segmented, FaqGrid, PlanTile, ImageCard, StatTile });
