// Loop MVP — shared UI primitives
// All components are kept compact and rooted in the Loop design system tokens.

// ─────────────────────────────────────────────────────────────
// Eyebrow — uppercase label with orange dot
// ─────────────────────────────────────────────────────────────
function Eyebrow({ children, style = {} }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      fontSize: 11, fontWeight: 700, letterSpacing: '0.08em',
      textTransform: 'uppercase', color: 'var(--ink)', ...style,
    }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--loop-orange-light)' }} />
      {children}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Avatar — circular initials OR photo, optional tint
// ─────────────────────────────────────────────────────────────
function Avatar({ initials, tint = 'var(--ink)', size = 40, ring = false, photo, style = {} }) {
  const [loaded, setLoaded] = React.useState(!photo);
  const [errored, setErrored] = React.useState(false);
  const showPhoto = photo && !errored;
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: tint, color: 'var(--canvas-lifted)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: Math.round(size * 0.38), fontWeight: 500, letterSpacing: '-0.02em',
      flexShrink: 0, overflow: 'hidden', position: 'relative',
      boxShadow: ring ? `0 0 0 3px var(--canvas-lifted), 0 0 0 4px ${tint}` : 'none',
      ...style,
    }}>
      {!showPhoto && <span>{initials}</span>}
      {showPhoto && (
        <img src={photo} alt=""
          onLoad={() => setLoaded(true)}
          onError={() => setErrored(true)}
          style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%',
            objectFit: 'cover', opacity: loaded ? 1 : 0,
            transition: 'opacity 300ms var(--ease-soft)',
          }} />
      )}
      {showPhoto && !loaded && <span>{initials}</span>}
    </div>
  );
}

// Look up a person record by name from data.js so participant rows can render with photos
function findPerson(nameOrInitials) {
  const all = (window.LOOP_DATA && window.LOOP_DATA.people) || [];
  return all.find(p => p.name === nameOrInitials || p.initials === nameOrInitials);
}

// Avatar cluster (stacked)
function AvatarStack({ people = [], size = 28, max = 4 }) {
  const show = people.slice(0, max);
  const extra = people.length - show.length;
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center' }}>
      {show.map((p, i) => (
        <div key={i} style={{ marginLeft: i === 0 ? 0 : -8, position: 'relative', zIndex: show.length - i }}>
          <Avatar initials={p.initials} tint={p.tint || 'var(--ink)'} size={size}
            photo={p.photo || (findPerson(p.initials) && findPerson(p.initials).photo)}
            style={{ boxShadow: '0 0 0 2px var(--canvas)' }} />
        </div>
      ))}
      {extra > 0 && (
        <div style={{
          marginLeft: -8, width: size, height: size, borderRadius: '50%',
          background: 'var(--dust)', color: 'var(--ink)', fontWeight: 500,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          fontSize: Math.round(size * 0.34), boxShadow: '0 0 0 2px var(--canvas)',
        }}>+{extra}</div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Card — sits directly on cream, no shadow by default
// ─────────────────────────────────────────────────────────────
function Card({ children, lifted = false, ink = false, style = {}, onClick }) {
  const bg = ink ? 'var(--ink)' : lifted ? 'var(--canvas-lifted)' : 'var(--canvas-lifted)';
  return (
    <div onClick={onClick} style={{
      background: bg, color: ink ? 'var(--canvas)' : 'var(--ink)',
      borderRadius: 24, padding: 20,
      boxShadow: lifted ? 'var(--shadow-2)' : 'none',
      cursor: onClick ? 'pointer' : 'default',
      transition: 'transform 200ms var(--ease-soft)',
      ...style,
    }}>{children}</div>
  );
}

// ─────────────────────────────────────────────────────────────
// Pill button — Loop's signature 20px-radius button
// ─────────────────────────────────────────────────────────────
function Button({ children, variant = 'primary', size = 'md', onClick, style = {}, icon = null, full = false }) {
  const base = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    fontFamily: 'var(--font-sans)', fontWeight: 500,
    letterSpacing: '-0.02em', lineHeight: 1,
    borderRadius: 20, border: '1.5px solid transparent',
    cursor: 'pointer', userSelect: 'none',
    transition: 'transform 120ms, background 200ms',
    padding: size === 'sm' ? '10px 5px' : '14px 22px',
    fontSize: size === 'sm' ? 14 : 16,
    width: full ? '100%' : 'auto',
  };
  const variants = {
    primary: { background: 'var(--ink)', color: 'var(--canvas)', borderColor: 'var(--ink)' },
    secondary: { background: 'transparent', color: 'var(--ink)', borderColor: 'var(--ink)' },
    ghost: { background: 'transparent', color: 'var(--ink)', borderColor: 'transparent' },
    signal: { background: 'var(--loop-orange)', color: 'var(--white)', borderColor: 'var(--loop-orange)' },
    onInk: { background: 'var(--canvas)', color: 'var(--ink)', borderColor: 'var(--canvas)' },
  };
  return (
    <button onClick={onClick} style={{ ...base, ...variants[variant], ...style }}>
      {icon}{children}
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// Icon — Lucide via the loaded CDN script (lucide.icons.<name>)
// Falls back to a tiny dot if lucide isn't available.
// ─────────────────────────────────────────────────────────────
function Icon({ name, size = 20, color = 'currentColor', style = {} }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!ref.current || !window.lucide) return;
    ref.current.innerHTML = '';
    const el = document.createElement('i');
    el.setAttribute('data-lucide', name);
    el.style.width = size + 'px';
    el.style.height = size + 'px';
    el.style.color = color;
    ref.current.appendChild(el);
    try { window.lucide.createIcons({ icons: window.lucide.icons }); } catch (e) {}
  }, [name, size, color]);
  return <span ref={ref} style={{ display: 'inline-flex', width: size, height: size, ...style }} />;
}

// ─────────────────────────────────────────────────────────────
// Top header — title + optional back + trailing slot
// ─────────────────────────────────────────────────────────────
function Header({ title, eyebrow, back, trailing, style = {}, large = false }) {
  return (
    <div style={{ padding: large ? '8px 22px 4px' : '8px 22px', ...style }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: 44 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginLeft: back ? -8 : 0 }}>
          {back && (
            <button onClick={back} style={{
              width: 40, height: 40, borderRadius: '50%', border: 'none',
              background: 'transparent', cursor: 'pointer',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)',
            }}>
              <Icon name="chevron-left" size={26} />
            </button>
          )}
          {!large && (
            <div>
              {eyebrow && <div style={{ marginBottom: 2 }}><Eyebrow>{eyebrow}</Eyebrow></div>}
              <div style={{ fontSize: 18, fontWeight: 500, letterSpacing: '-0.02em' }}>{title}</div>
            </div>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>{trailing}</div>
      </div>
      {large && (
        <div style={{ marginTop: 8 }}>
          {eyebrow && <div style={{ marginBottom: 6 }}><Eyebrow>{eyebrow}</Eyebrow></div>}
          <h1 style={{ fontSize: 34, fontWeight: 500, letterSpacing: '-0.025em', lineHeight: 1.05, margin: 0 }}>{title}</h1>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Bottom tab bar — 5 tabs. Sits as a normal flex child at the
// bottom of the device column, so internal scrolling never
// affects it (no position:absolute / no stacking-context risk).
// ─────────────────────────────────────────────────────────────
function TabBar({ tabs, current, onPick }) {
  const isPhone = useIsPhone();
  return (
    <div style={{
      flexShrink: 0,
      // Framed mockup: 34px clears the fake home-indicator zone.
      // Frameless phone: hug the real OS home bar via safe-area inset.
      paddingBottom: isPhone
        ? 'calc(env(safe-area-inset-bottom, 0px) + 8px)'
        : 34,
      paddingTop: 8, paddingLeft: 8, paddingRight: 8,
      background: 'var(--canvas)',
      borderTop: '1px solid rgba(20,20,19,0.06)',
      display: 'flex', justifyContent: 'space-around',
      // Phone: pin to the viewport bottom so it never scrolls away.
      // Desktop: normal flex child at the bottom of the device column.
      ...(isPhone
        ? { position: 'fixed', left: 0, right: 0, bottom: 0, zIndex: 100 }
        : { position: 'relative', zIndex: 30 }),
    }}>
      {tabs.map(t => {
        const active = current === t.key;
        return (
          <button key={t.key} onClick={() => onPick(t.key)} style={{
            display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: 4,
            background: 'transparent', border: 'none', cursor: 'pointer',
            padding: '6px 10px', width: 64,
            color: active ? 'var(--ink)' : 'var(--slate)',
          }}>
            <Icon name={t.icon} size={22} />
            <span style={{ fontSize: 10, fontWeight: active ? 700 : 500, letterSpacing: '0.02em' }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Scroll container — body of every screen
// ─────────────────────────────────────────────────────────────
function Screen({ children, style = {}, padBottom = 24 }) {
  return (
    <div style={{
      flex: 1, overflowY: 'auto', overflowX: 'hidden',
      paddingBottom: padBottom,
      WebkitOverflowScrolling: 'touch',
      ...style,
    }}>{children}</div>
  );
}

// ─────────────────────────────────────────────────────────────
// Chip — small inline label
// ─────────────────────────────────────────────────────────────
function Chip({ children, tone = 'default', style = {} }) {
  const tones = {
    default: { bg: 'var(--canvas-whisper)', fg: 'var(--ink)' },
    ink: { bg: 'var(--ink)', fg: 'var(--canvas)' },
    signal: { bg: 'var(--loop-orange-light)', fg: 'var(--white)' },
    success: { bg: 'rgba(31,122,77,0.12)', fg: 'var(--success)' },
    danger: { bg: 'rgba(177,35,24,0.12)', fg: 'var(--danger)' },
    warning: { bg: 'rgba(207,69,0,0.12)', fg: 'var(--loop-orange)' },
    muted: { bg: 'transparent', fg: 'var(--slate)' },
  };
  const t = tones[tone] || tones.default;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '4px 10px', borderRadius: 999,
      background: t.bg, color: t.fg,
      fontSize: 11, fontWeight: 700, letterSpacing: '0.04em',
      textTransform: 'uppercase', whiteSpace: 'nowrap',
      ...style,
    }}>{children}</span>
  );
}

// ─────────────────────────────────────────────────────────────
// Row — generic tappable row in a list card
// ─────────────────────────────────────────────────────────────
function Row({ leading, title, subtitle, trailing, onClick, divider = true, style = {} }) {
  return (
    <div onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '14px 0',
      borderBottom: divider ? '1px solid rgba(20,20,19,0.06)' : 'none',
      cursor: onClick ? 'pointer' : 'default',
      ...style,
    }}>
      {leading}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 15, fontWeight: 500, letterSpacing: '-0.01em', color: 'var(--ink)' }}>{title}</div>
        {subtitle && <div style={{ fontSize: 13, color: 'var(--slate)', marginTop: 2 }}>{subtitle}</div>}
      </div>
      {trailing}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Section — eyebrow + heading + body
// ─────────────────────────────────────────────────────────────
function Section({ eyebrow, title, action, children, style = {} }) {
  return (
    <section style={{ padding: '8px 22px 0', ...style }}>
      {(eyebrow || title || action) && (
        <header style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 14 }}>
          <div>
            {eyebrow && <div style={{ marginBottom: 6 }}><Eyebrow>{eyebrow}</Eyebrow></div>}
            {title && <h2 style={{ fontSize: 22, fontWeight: 500, letterSpacing: '-0.02em', margin: 0 }}>{title}</h2>}
          </div>
          {action}
        </header>
      )}
      {children}
    </section>
  );
}

// Satellite CTA — white circle, docked CTA
function SatelliteCTA({ icon = 'arrow-up-right', onClick, size = 48, tint, style = {} }) {
  return (
    <button onClick={onClick} style={{
      width: size, height: size, borderRadius: '50%',
      background: tint || 'var(--white)', color: 'var(--ink)',
      border: 'none', cursor: 'pointer',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: '0 8px 20px rgba(0,0,0,0.08)', ...style,
    }}><Icon name={icon} size={Math.round(size * 0.45)} /></button>
  );
}

// Status dot — small colored signal
function Dot({ tone = 'default', size = 8, style = {} }) {
  const colors = {
    default: 'var(--slate)',
    high: 'var(--loop-orange)',
    med: 'var(--loop-orange-light)',
    low: 'var(--dust)',
    success: 'var(--success)',
    danger: 'var(--danger)',
  };
  return <span style={{ display: 'inline-block', width: size, height: size, borderRadius: '50%', background: colors[tone] || colors.default, ...style }} />;
}

// Orange orbital arc — the Loop signature
function OrbitalArc({ width = 320, height = 80, opacity = 0.7, style = {} }) {
  return (
    <svg viewBox={`0 0 ${width} ${height}`} width="100%" style={style}
      preserveAspectRatio="none" fill="none">
      <path d={`M0,${height - 10} Q${width / 2},-${height * 0.4} ${width},${height - 10}`}
        stroke="var(--loop-orange-light)" strokeWidth="1.2" opacity={opacity}
        strokeDasharray="0" />
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// CompanyLogo — programmatic brand marks on a tinted square.
// Each company id maps to a distinctive geometric glyph.
// ─────────────────────────────────────────────────────────────
function CompanyLogo({ company, size = 36, rounded = 8 }) {
  if (!company) return null;
  const marks = {
    // Helix — interlocking arcs (helical strand)
    helix: (
      <g stroke="var(--canvas)" strokeWidth="2.4" fill="none" strokeLinecap="round">
        <path d="M9 7 C16 7, 16 17, 9 17 C16 17, 16 27, 9 27" />
        <path d="M23 7 C16 7, 16 17, 23 17 C16 17, 16 27, 23 27" />
      </g>
    ),
    // Caldera — concentric rings, top-right offset
    caldera: (
      <g fill="none" stroke="var(--canvas)" strokeWidth="2">
        <circle cx="16" cy="16" r="11" />
        <circle cx="16" cy="16" r="6.5" />
        <circle cx="16" cy="16" r="2.2" fill="var(--canvas)" />
      </g>
    ),
    // Northstar — 8-point asterisk
    northstar: (
      <g stroke="var(--canvas)" strokeWidth="2.4" strokeLinecap="round">
        <line x1="16" y1="6" x2="16" y2="26" />
        <line x1="6" y1="16" x2="26" y2="16" />
        <line x1="9" y1="9" x2="23" y2="23" />
        <line x1="23" y1="9" x2="9" y2="23" />
      </g>
    ),
    // Sandera — S-wave curve
    sandera: (
      <path d="M8 22 C8 16, 14 16, 16 16 S24 16, 24 10"
        stroke="var(--canvas)" strokeWidth="2.4" fill="none" strokeLinecap="round" />
    ),
  };
  const mark = marks[company.id] || (
    <text x="16" y="21" textAnchor="middle"
      fontFamily="Sofia Sans, -apple-system, sans-serif"
      fontSize="14" fontWeight="600" fill="var(--canvas)" letterSpacing="-0.02em">
      {company.initials}
    </text>
  );
  return (
    <div style={{
      width: size, height: size, borderRadius: rounded,
      background: company.tint, flexShrink: 0,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <svg viewBox="0 0 32 32" width={Math.round(size * 0.78)} height={Math.round(size * 0.78)}>
        {mark}
      </svg>
    </div>
  );
}

Object.assign(window, {
  Eyebrow, Avatar, AvatarStack, Card, Button, Icon, Header, TabBar, Screen,
  Chip, Row, Section, SatelliteCTA, Dot, OrbitalArc, findPerson, CompanyLogo,
});
