// ─────────────────────────────────────────────────────────────────────────
//  shared.jsx — icons, primitives, helpers shared across all robot screens
// ─────────────────────────────────────────────────────────────────────────
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ── Icon set (inline stroke SVGs, no emoji) ────────────────────────────────
const ICON_PATHS = {
  mic:        'M12 2a3 3 0 0 0-3 3v6a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3zM5 10v1a7 7 0 0 0 14 0v-1M12 19v3',
  person:     'M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21v-1a6 6 0 0 1 6-6h4a6 6 0 0 1 6 6v1',
  calendar:   'M7 3v3M17 3v3M4 8h16M5 5h14a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1z',
  package:    'M21 8l-9-5-9 5 9 5 9-5zM3 8v8l9 5 9-5V8M12 13v8',
  faq:        'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM9.5 9a2.5 2.5 0 0 1 4.5 1.5c0 1.5-2 2-2 3.5M12 17h.01',
  megaphone:  'M3 11v2a1 1 0 0 0 1 1h2l4 4V6L6 10H4a1 1 0 0 0-1 1zM15 8a4 4 0 0 1 0 8M18 5a8 8 0 0 1 0 14',
  shield:     'M12 3l8 3v6c0 4-3.5 7.5-8 9-4.5-1.5-8-5-8-9V6l8-3z',
  clock:      'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 7v5l3 2',
  history:    'M3 3v5h5M3.05 13A9 9 0 1 0 6 5.3L3 8M12 7v5l4 2',
  home:       'M3 11l9-8 9 8M5 9v11a1 1 0 0 0 1 1h4v-6h4v6h4a1 1 0 0 0 1-1V9',
  help:       'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM9.5 9a2.5 2.5 0 0 1 4.5 1.5c0 1.5-2 2-2 3.5M12 17h.01',
  arrowRight: 'M5 12h14M13 6l6 6-6 6',
  arrowLeft:  'M19 12H5M11 18l-6-6 6-6',
  check:      'M20 6L9 17l-5-5',
  checkCircle:'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM8 12l3 3 5-6',
  x:          'M18 6L6 18M6 6l12 12',
  edit:       'M12 20h9M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z',
  send:       'M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z',
  search:     'M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.3-4.3',
  mapPin:     'M12 21s-7-5.5-7-11a7 7 0 0 1 14 0c0 5.5-7 11-7 11zM12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  globe:      'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20',
  qr:         'M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM14 14h2v2h-2zM18 14h2v2h-2zM14 18h2v2h-2zM18 18h2v2h-2z',
  volume:     'M11 5L6 9H2v6h4l5 4V5zM15.5 8.5a5 5 0 0 1 0 7M19 5a9 9 0 0 1 0 14',
  battery:    'M3 7h14a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H3a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zM22 10v4',
  wifi:       'M5 12.5a10 10 0 0 1 14 0M8.5 16a5 5 0 0 1 7 0M12 19.5h.01',
  robot:      'M12 2v3M8 8h8a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2zM9 13h.01M15 13h.01M9 17h6',
  route:      'M6 19a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM18 9a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM8 17h6a4 4 0 0 0 0-8H8',
  pause:      'M8 5v14M16 5v14',
  play:       'M6 4l14 8-14 8V4z',
  bell:       'M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9zM13.7 21a2 2 0 0 1-3.4 0',
  chevron:    'M9 6l6 6-6 6',
  settings:   'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-2.82 1.17V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 8 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 3.6 14H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 8.6l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 6.4h.09A1.65 1.65 0 0 0 10.6 4.8V4a2 2 0 0 1 4 0v.09c.36.14.68.36.94.66',
  list:       'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01',
  refresh:    'M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5',
  coffee:     'M18 8h1a3 3 0 0 1 0 6h-1M3 8h15v6a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V8zM6 2v2M10 2v2M14 2v2',
  mail:       'M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM3 7l9 6 9-6',
  doc:        'M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5zM14 3v5h5M9 13h6M9 17h6',
  gift:       'M20 12v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-8M2 7h20v5H2zM12 21V7M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7zM12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z',
  users:      'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75',
  alert:      'M12 9v4M12 17h.01M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z',
  plus:       'M12 5v14M5 12h14',
  camera:     'M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2zM12 17a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  stop:       'M6 6h12v12H6z',
};

function Icon({ name, size = 24, color = 'currentColor', stroke = 2, fill = 'none', style }) {
  const d = ICON_PATHS[name] || '';
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={color}
      strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      style={{ flexShrink: 0, ...style }}>
      {d.split('M').filter(Boolean).map((seg, i) => <path key={i} d={'M' + seg} />)}
    </svg>
  );
}

// ── Animated voice waveform ────────────────────────────────────────────────
function Waveform({ active, color = '#0E9C84', bars = 28, height = 88, width = 360 }) {
  const [t, setT] = useState(0);
  useEffect(() => {
    if (!active) return;
    let raf, start = performance.now();
    const loop = now => { setT((now - start) / 1000); raf = requestAnimationFrame(loop); };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [active]);
  const arr = Array.from({ length: bars });
  const bw = width / bars;
  return (
    <svg width={width} height={height} style={{ display: 'block' }}>
      {arr.map((_, i) => {
        const phase = i * 0.45;
        const env = Math.sin((i / bars) * Math.PI); // taper edges
        const amp = active
          ? (0.25 + 0.75 * Math.abs(Math.sin(t * 6 + phase)) * (0.4 + 0.6 * env))
          : 0.08 + 0.04 * env;
        const h = Math.max(4, amp * height);
        return (
          <rect key={i} x={i * bw + bw * 0.2} y={(height - h) / 2}
            width={bw * 0.6} height={h} rx={bw * 0.3}
            fill={color} opacity={active ? (0.55 + 0.45 * env) : 0.3} />
        );
      })}
    </svg>
  );
}

// ── Status pill ────────────────────────────────────────────────────────────
function Pill({ tone = 'neutral', children, style }) {
  const tones = {
    neutral: { bg: 'rgba(31,42,51,0.07)', c: '#5C6B76' },
    blue:    { bg: 'rgba(31,111,178,0.12)', c: '#1F6FB2' },
    green:   { bg: 'rgba(11,122,107,0.13)', c: '#0B7A6B' },
    amber:   { bg: 'rgba(199,119,0,0.14)',  c: '#9A5B00' },
    red:     { bg: 'rgba(209,67,67,0.14)',   c: '#C0392B' },
  };
  const tn = tones[tone] || tones.neutral;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 12px',
      borderRadius: 999, background: tn.bg, color: tn.c, fontSize: 14, fontWeight: 600,
      letterSpacing: '0.02em', ...style }}>{children}</span>
  );
}

// ── Live clock ─────────────────────────────────────────────────────────────
function useClock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []);
  return now;
}
const fmtTime = d => d.toLocaleTimeString('ja-JP', { hour: '2-digit', minute: '2-digit' });
const fmtDate = d => `${d.getMonth() + 1}月${d.getDate()}日(${'日月火水木金土'[d.getDay()]})`;

// expose
Object.assign(window, { Icon, Waveform, Pill, useClock, fmtTime, fmtDate,
  useState, useEffect, useRef, useMemo, useCallback });
