/* =========================================================
   Shared components & hooks
   ========================================================= */

const { useState, useEffect, useRef, useMemo, useLayoutEffect, useCallback } = React;

/* ---------- Logo wordmark ---------- */
function Wordmark({ size = 22, color = 'currentColor' }) {
  return (
    <div className="ecom-logo" style={{ display: 'inline-flex', alignItems: 'center', gap: 8, color, fontFamily: 'var(--font-sans)', fontWeight: 600, fontSize: size, letterSpacing: '-0.02em' }}>
      <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: size * 1.15, height: size * 1.15, borderRadius: '50%', background: 'var(--green)', color: 'white', fontWeight: 700, fontSize: size * 0.6 }}>e</span>
      <span>ecomlifters</span>
    </div>
  );
}

/* ---------- Hugeicons-style SVG icon set ---------- */
const Icon = {
  Arrow: ({ size = 14, rotate = -45 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{ transform: `rotate(${rotate}deg)`, flexShrink: 0 }}>
      <path d="M5 12h14"/><path d="M13 6l6 6-6 6"/>
    </svg>
  ),
  ArrowDown: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 5v14"/><path d="M6 13l6 6 6-6"/>
    </svg>
  ),
  Plus: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
      <path d="M12 5v14M5 12h14"/>
    </svg>
  ),
  Check: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4.5 12.75l6 6 9-13.5"/>
    </svg>
  ),
  X: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
      <path d="M6 6l12 12M6 18L18 6"/>
    </svg>
  ),
  Star: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor">
      <path d="M11.245 4.174a.85.85 0 011.51 0l1.878 3.805 4.2.61a.85.85 0 01.471 1.45l-3.04 2.962.718 4.183a.85.85 0 01-1.233.895L12 15.933l-3.749 1.97a.85.85 0 01-1.233-.895l.718-4.183-3.04-2.963a.85.85 0 01.471-1.45l4.2-.61z"/>
    </svg>
  ),
  Play: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M6 4.75l13.5 7.25L6 19.25V4.75z"/>
    </svg>
  ),
  TrendUp: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 17l4.5-4.5 3.5 3.5L17 9M13 9h4v4"/>
    </svg>
  ),
  TrendDown: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 7l4.5 4.5 3.5-3.5L17 15M13 15h4v-4"/>
    </svg>
  ),
  Dot: () => <span style={{ width: 4, height: 4, borderRadius: '50%', background: 'currentColor', display: 'inline-block', opacity: .4 }}></span>,
  Calendar: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="5" width="18" height="16" rx="2"/><path d="M16 3v4M8 3v4M3 9h18"/>
    </svg>
  ),
  Globe: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
      <circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c-2.796 3-4.5 5.4-4.5 9s1.704 6 4.5 9M12 3c2.796 3 4.5 5.4 4.5 9s-1.704 6-4.5 9"/>
    </svg>
  ),
  Mail: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="4" width="20" height="16" rx="2"/><path d="M2 7l10 7 10-7"/>
    </svg>
  ),
  Phone: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M6.5 2h11a1 1 0 011 1v18a1 1 0 01-1 1h-11a1 1 0 01-1-1V3a1 1 0 011-1z"/><circle cx="12" cy="18.5" r=".75" fill="currentColor"/>
    </svg>
  ),
  Location: ({ size = 14 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/>
    </svg>
  ),
};

/* ---------- Reveal on scroll ---------- */
function useReveal(threshold = 0.12) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { el.classList.add('in'); io.disconnect(); }
    }, { threshold });
    io.observe(el);
    return () => io.disconnect();
  }, [threshold]);
  return ref;
}

function Reveal({ children, delay = 0, as: As = 'div', className = '', style = {}, ...rest }) {
  const ref = useReveal();
  return (
    <As ref={ref} className={`reveal ${className}`} style={{ transitionDelay: `${delay}ms`, ...style }} {...rest}>
      {children}
    </As>
  );
}

/* ---------- Animated counter (counts when in view) ---------- */
function Counter({ to, prefix = '', suffix = '', duration = 1800, decimals = 0 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  const started = useRef(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !started.current) {
        started.current = true;
        const t0 = performance.now();
        const tick = (t) => {
          const k = Math.min(1, (t - t0) / duration);
          const eased = 1 - Math.pow(1 - k, 3);
          setVal(to * eased);
          if (k < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
      }
    }, { threshold: 0.3 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const formatted = decimals
    ? val.toFixed(decimals)
    : Math.round(val).toLocaleString('en-US');
  return <span ref={ref} className="num">{prefix}{formatted}{suffix}</span>;
}

/* ---------- Sparkline ---------- */
function Sparkline({ values, width = 120, height = 36, color = 'var(--green)', fill = true, strokeWidth = 1.6 }) {
  const min = Math.min(...values), max = Math.max(...values);
  const range = max - min || 1;
  const stepX = width / (values.length - 1);
  const pts = values.map((v, i) => [i * stepX, height - 4 - ((v - min) / range) * (height - 8)]);
  const d = pts.map((p, i) => `${i ? 'L' : 'M'}${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(' ');
  const area = `${d} L${width},${height} L0,${height} Z`;
  const gid = useMemo(() => 'spk' + Math.random().toString(36).slice(2, 8), []);
  return (
    <svg className="spark" width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <defs>
        <linearGradient id={gid} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      {fill && <path d={area} fill={`url(#${gid})`} />}
      <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.4" fill={color} />
    </svg>
  );
}

/* ---------- Bar mini chart ---------- */
function BarChart({ data, width = 120, height = 36, color = 'var(--green)', bg = 'var(--hairline)' }) {
  const max = Math.max(...data) || 1;
  const bw = width / data.length;
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      {data.map((v, i) => {
        const h = (v / max) * (height - 2);
        return <rect key={i} x={i * bw + 1} y={height - h} width={bw - 2} height={h} rx="1" fill={v === max ? color : bg} />;
      })}
    </svg>
  );
}

/* ---------- Buttons ---------- */
function BtnDark({ children = 'Call Us', icon = true, onClick, style }) {
  return (
    <button className="btn btn-dark" onClick={onClick} style={style}>
      <span>{children}</span>
      {icon && <span className="ico"><Icon.Arrow size={12} /></span>}
    </button>
  );
}
function BtnGreen({ children = 'Instant Response', icon = true, onClick, style }) {
  return (
    <button className="btn btn-green" onClick={onClick} style={style}>
      <span>{children}</span>
      {icon && <span className="ico"><Icon.Arrow size={12} /></span>}
    </button>
  );
}
function BtnGhost({ children = 'Learn more', icon = true, onClick, style }) {
  return (
    <button className="btn btn-ghost" onClick={onClick} style={style}>
      <span>{children}</span>
      {icon && <Icon.Arrow size={14} />}
    </button>
  );
}

/* ---------- Sticky annotation sticker ---------- */
function Sticker({ children, src, rotate = -3, style }) {
  return (
    <div className="sticker" style={{ transform: `rotate(${rotate}deg)`, ...style }}>
      <span>{children}</span>
      {src && <span className="src">— {src}</span>}
    </div>
  );
}

/* ---------- Image placeholder (subtle stripes + monospace caption) ---------- */
function Placeholder({ label = 'image', height = 200, ratio, style, color = 'var(--green-deep)' }) {
  return (
    <div style={{
      width: '100%',
      aspectRatio: ratio,
      height: ratio ? undefined : height,
      borderRadius: 'var(--r-md)',
      background: 'repeating-linear-gradient(135deg, #EFEDE5 0 8px, #E6E3D9 8px 16px)',
      border: '1px solid var(--hairline)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color, fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase',
      ...style,
    }}>
      [ {label} ]
    </div>
  );
}

/* ---------- Avatar circle (initials + tinted bg) ---------- */
function Avatar({ name, size = 32, hue }) {
  const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase();
  const h = hue ?? (name.charCodeAt(0) * 17 % 360);
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: `oklch(0.78 0.07 ${h})`,
      color: `oklch(0.32 0.08 ${h})`,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'var(--font-sans)', fontWeight: 600, fontSize: size * 0.4,
      border: '2px solid white',
    }}>{initials}</div>
  );
}

/* ---------- Section header ---------- */
function SectionHeader({ eyebrow, title, lead, align = 'left', children }) {
  return (
    <div style={{ textAlign: align, display: 'flex', flexDirection: 'column', alignItems: align === 'center' ? 'center' : 'flex-start', gap: 18, marginBottom: 56 }}>
      {eyebrow && <Reveal><span className="eyebrow"><span className="dot"></span>{eyebrow}</span></Reveal>}
      {title && <Reveal delay={80}><h2 className="h2" style={{ maxWidth: 900 }}>{title}</h2></Reveal>}
      {lead && <Reveal delay={160}><p className="lead">{lead}</p></Reveal>}
      {children}
    </div>
  );
}

/* ---------- Window-width hook (for inline-style responsive layouts) ---------- */
function useWindowWidth() {
  const [w, setW] = React.useState(typeof window !== 'undefined' ? window.innerWidth : 1200);
  React.useEffect(() => {
    const fn = () => setW(window.innerWidth);
    window.addEventListener('resize', fn, { passive: true });
    return () => window.removeEventListener('resize', fn);
  }, []);
  return w;
}

/* ---------- Export to window so other files see them ---------- */
Object.assign(window, {
  Wordmark, Icon, useReveal, Reveal, Counter, Sparkline, BarChart,
  BtnDark, BtnGreen, BtnGhost, Sticker, Placeholder, Avatar, SectionHeader,
  useWindowWidth,
});
