// ============ Yap — shared components ============
const { useState, useRef, useEffect, useLayoutEffect } = React;

// ---- Icon set (simple stroke glyphs) ----
const ICONS = {
  chat:    'M21 11.5a8.38 8.38 0 0 1-8.5 8.5 9 9 0 0 1-3.8-.8L3 21l1.9-5.2A8.5 8.5 0 1 1 21 11.5z',
  feed:    'M3 10.5 12 4l9 6.5M5 9.5V20h14V9.5',
  bell:    'M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0',
  user:    'M20 21a8 8 0 1 0-16 0M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',
  search:  'M11 18a7 7 0 1 0 0-14 7 7 0 0 0 0 14zM20 20l-3.5-3.5',
  back:    'M15 19l-7-7 7-7',
  send:    'M5 12h14M13 6l6 6-6 6',
  plus:    'M12 5v14M5 12h14',
  camera:  'M4 8.5A1.5 1.5 0 0 1 5.5 7H8l1.2-1.8a1 1 0 0 1 .8-.4h4a1 1 0 0 1 .8.4L16 7h2.5A1.5 1.5 0 0 1 20 8.5V18a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 4 18V8.5zM12 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  heart:   'M12 20.5s-7-4.6-9.3-9C1.2 8.7 2.6 5.5 5.8 5.5c2 0 3.3 1.2 4.2 2.5.9-1.3 2.2-2.5 4.2-2.5 3.2 0 4.6 3.2 3.1 6-2.3 4.4-9.3 9-9.3 9z',
  comment: 'M21 11.5a8.38 8.38 0 0 1-8.5 8.5 9 9 0 0 1-3.8-.8L3 21l1.9-5.2A8.5 8.5 0 1 1 21 11.5z',
  share:   'M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7M16 6l-4-4-4 4M12 2v13',
  more:    'M12 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM19 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM5 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z',
  check:   'M5 12.5l4.5 4.5L19 7',
  checks:  'M2 12.5l4.5 4.5M9 12.5l4.5 4.5L22 7M12.5 13.5 18 8',
  phone:   'M16.5 21a16 16 0 0 1-13.5-13.5 2 2 0 0 1 2-2.3h2.5a1 1 0 0 1 1 .8l.8 3a1 1 0 0 1-.3 1L9.3 11.3a13 13 0 0 0 3.4 3.4l1.3-1.4a1 1 0 0 1 1-.3l3 .8a1 1 0 0 1 .8 1V18a2 2 0 0 1-2.3 2z',
  video:   'M3 8.5A1.5 1.5 0 0 1 4.5 7h9A1.5 1.5 0 0 1 15 8.5v7A1.5 1.5 0 0 1 13.5 17h-9A1.5 1.5 0 0 1 3 15.5v-7zM15 11l6-3.5v9L15 13',
  smiley:  'M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18zM9 10h.01M15 10h.01M8.5 14.5a4 4 0 0 0 7 0',
  mic:     'M12 15a3 3 0 0 0 3-3V6a3 3 0 0 0-6 0v6a3 3 0 0 0 3 3zM5 11a7 7 0 0 0 14 0M12 18.5V22',
  settings:'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM19.4 13a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1a1.6 1.6 0 0 0-2.7-1.1l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 4 13H3.9a2 2 0 1 1 0-4H4a1.6 1.6 0 0 0 1.1-2.7l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 11 4V3.9a2 2 0 1 1 4 0V4a1.6 1.6 0 0 0 2.7 1.1l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1A1.6 1.6 0 0 0 20 11h.1a2 2 0 1 1 0 4H20a1.6 1.6 0 0 0-.6.9z',
  edit:    'M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z',
  bookmark:'M6 4h12v16l-6-4-6 4V4z',
  grid:    'M4 4h7v7H4zM13 4h7v7h-7zM13 13h7v7h-7zM4 13h7v7H4z',
  at:      'M16 12a4 4 0 1 0-4 4M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8',
  userplus:'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 8zM19 8v6M22 11h-6',
  pin:     'M9 4h6l-1 5 3 3v2H7v-2l3-3-1-5zM12 16v5',
  lock:    'M5 11h14v9H5zM8 11V7a4 4 0 0 1 8 0v4',
  arrow:   'M5 12h14M13 6l6 6-6 6',
  close:   'M6 6l12 12M18 6 6 18',
};

function Icon({ name, size = 22, stroke = 2, fill = 'none', style, color }) {
  const d = ICONS[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill === 'current' ? 'currentColor' : 'none'}
      stroke={fill === 'current' ? 'none' : 'currentColor'} strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round" style={{ display: 'block', color, ...style }}>
      <path d={d} />
    </svg>
  );
}

// ---- Avatar (gradient + initials, or placeholder image) ----
function Avatar({ who, size = 48, ring = null, story = false, seen = false }) {
  const p = typeof who === 'string' ? person(who) : who;
  const hue = (p && p.hue != null) ? p.hue : 0;
  const v1 = AVATAR_VARS[hue % AVATAR_VARS.length];
  const v2 = AVATAR_VARS[(hue + 3) % AVATAR_VARS.length];
  const isMe = p && (p.id === 'me');
  const inner = (
    <div style={{
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      background: isMe
        ? 'linear-gradient(140deg, var(--brand), var(--brand-deep))'
        : `linear-gradient(140deg, var(${v1}), var(${v2}))`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: 'white', fontWeight: 800, fontSize: size * 0.36,
      letterSpacing: '-0.02em', fontFamily: 'var(--font-ui)',
      boxShadow: 'inset 0 0 0 1px oklch(1 0 0 / 0.18)',
    }}>
      {p ? initials(p.name) : '?'}
    </div>
  );
  if (story) {
    return (
      <div style={{
        padding: 3, borderRadius: '50%',
        background: seen ? 'var(--line)' : 'linear-gradient(140deg, var(--c-pink), var(--brand), var(--c-sky))',
      }}>
        <div style={{ padding: 2.5, borderRadius: '50%', background: 'var(--bg)' }}>{inner}</div>
      </div>
    );
  }
  if (ring) {
    return <div style={{ padding: 2.5, borderRadius: '50%', background: ring }}>
      <div style={{ padding: 2, borderRadius: '50%', background: 'var(--bg)' }}>{inner}</div></div>;
  }
  return inner;
}

// Online dot wrapper
function Presence({ children, online, size = 13 }) {
  return (
    <div style={{ position: 'relative', flexShrink: 0 }}>
      {children}
      {online && (
        <span style={{
          position: 'absolute', right: 0, bottom: 0, width: size, height: size,
          borderRadius: '50%', background: 'var(--c-lime)',
          border: '2.5px solid var(--bg)',
        }} />
      )}
    </div>
  );
}

// ---- Bottom navigation ----
function BottomNav({ tab, onTab, unreadChats, unreadNotifs }) {
  const items = [
    { id: 'chats', icon: 'chat',  label: 'Messages', badge: unreadChats },
    { id: 'feed',  icon: 'feed',  label: 'Feed' },
    { id: 'notifs',icon: 'bell',  label: 'Activité', badge: unreadNotifs },
    { id: 'profile',icon: 'user', label: 'Profil' },
  ];
  return (
    <nav className="bottomnav">
      {items.map(it => {
        const active = tab === it.id;
        return (
          <button key={it.id} className="navbtn" data-active={active} onClick={() => onTab(it.id)}>
            <div style={{ position: 'relative' }}>
              <Icon name={it.icon} size={25} stroke={active ? 2.4 : 2}
                fill={active ? 'current' : 'none'} />
              {it.badge > 0 && <span className="navbtn__badge">{it.badge > 9 ? '9+' : it.badge}</span>}
            </div>
            <span className="navbtn__label">{it.label}</span>
          </button>
        );
      })}
    </nav>
  );
}

// ---- Reusable header ----
function TopBar({ children, border = false, style }) {
  return <header className={'topbar' + (border ? ' topbar--border' : '')} style={style}>{children}</header>;
}

Object.assign(window, { Icon, Avatar, Presence, BottomNav, TopBar });
