// ui.jsx — shared building blocks: placeholders, cards, chips, primitives

const { useMemo } = React;

// Photographic placeholder — tinted iconographic frame with subtle texture + label
function SaintPlaceholder({ tone = 'rose', label = 'Saint of the day', size = 'md', dark = false, halo = false }) {
  const t = window.TOKENS;
  const palette = {
    rose:  { a: '#E8C0BA', b: '#C99A98', c: '#A87878' },
    blush: { a: '#F0D5CE', b: '#D9A6A0', c: '#B07A7A' },
    cream: { a: '#EDE0CC', b: '#D6BFA0', c: '#A8896A' },
    sage:  { a: '#D2DCC2', b: '#A8B89A', c: '#7A8A6E' },
    gold:  { a: '#E8D4A8', b: '#C9A878', c: '#9A7C50' },
    violet:{ a: '#D8CCDF', b: '#9D8AA8', c: '#6E5C7E' },
  }[tone] || { a:'#E8C0BA', b:'#C99A98', c:'#A87878' };
  const sizing = { sm: 64, md: 96, lg: 132, xl: 200, hero: 240 }[size];
  const radius = size === 'sm' ? 14 : size === 'md' ? 18 : 24;

  // Iconographic placeholder: arched window + halo silhouette + monospace tag
  return (
    <div style={{
      width: sizing, height: sizing * 1.18, borderRadius: radius,
      background: `linear-gradient(160deg, ${palette.a}, ${palette.b})`,
      position: 'relative', overflow: 'hidden', flexShrink: 0,
      boxShadow: dark ? '0 4px 18px rgba(0,0,0,0.4)' : '0 4px 18px rgba(120,80,80,0.12)',
    }}>
      {/* arched window frame */}
      <div style={{
        position: 'absolute', inset: '10% 12% 14% 12%',
        borderRadius: '50% 50% 8% 8% / 28% 28% 8% 8%',
        background: `linear-gradient(180deg, ${palette.b}, ${palette.c})`,
        opacity: 0.55,
      }}/>
      {/* halo */}
      {halo && (
        <div style={{
          position: 'absolute', top: '20%', left: '50%', transform: 'translateX(-50%)',
          width: sizing * 0.42, height: sizing * 0.42, borderRadius: '50%',
          background: 'radial-gradient(circle, rgba(255,240,210,0.55), rgba(255,240,210,0))',
        }}/>
      )}
      {/* silhouette: simple bust shape */}
      <div style={{
        position: 'absolute', bottom: '14%', left: '50%', transform: 'translateX(-50%)',
        width: sizing * 0.42, height: sizing * 0.55,
        background: palette.c,
        borderRadius: `${sizing*0.25}px ${sizing*0.25}px 0 0 / ${sizing*0.32}px ${sizing*0.32}px 0 0`,
        opacity: 0.85,
      }}/>
      <div style={{
        position: 'absolute', bottom: '40%', left: '50%', transform: 'translateX(-50%)',
        width: sizing * 0.22, height: sizing * 0.22, borderRadius: '50%',
        background: palette.c, opacity: 0.85,
      }}/>
      {/* fine grain */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'repeating-linear-gradient(45deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 5px)',
      }}/>
      {/* label tag */}
      <div style={{
        position: 'absolute', left: 8, bottom: 8,
        fontFamily: 'ui-monospace, "SF Mono", Menlo, monospace',
        fontSize: 9, letterSpacing: 0.4, color: 'rgba(255,255,255,0.85)',
        textTransform: 'uppercase',
      }}>{label}</div>
    </div>
  );
}

function LiturgicalDot({ color = 'W', size = 8 }) {
  const c = window.TOKENS.liturgical[color]?.fg || '#888';
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%',
      background: c, display: 'inline-block', flexShrink: 0,
    }}/>
  );
}

function Chip({ children, tone = 'neutral', dark = false, small = false }) {
  const t = window.TOKENS;
  const styles = {
    neutral: {
      bg: dark ? 'rgba(255,250,240,0.06)' : 'rgba(60,55,70,0.06)',
      fg: dark ? t.inkSoft.dark : t.inkSoft.light,
    },
    rose: { bg: 'rgba(217,166,160,0.18)', fg: '#9E5E5E' },
    sage: { bg: 'rgba(168,184,154,0.22)', fg: '#5A7050' },
    gold: { bg: 'rgba(201,168,120,0.22)', fg: '#8A6A38' },
    premium: { bg: 'rgba(201,168,120,0.18)', fg: '#8A6A38' },
  }[tone] || { bg: 'rgba(60,55,70,0.06)', fg: '#615A66' };
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: small ? '3px 8px' : '5px 10px',
      borderRadius: 999,
      background: styles.bg, color: styles.fg,
      fontSize: small ? 11 : 12, fontWeight: 600, letterSpacing: 0.1,
      whiteSpace: 'nowrap',
    }}>{children}</span>
  );
}

// Bottom tab bar
function TabBar({ active = 'home', onChange, dark = false }) {
  const t = window.TOKENS;
  const items = [
    { id: 'home',    label: 'Today',   icon: 'home' },
    { id: 'journey', label: 'Journey', icon: 'journey' },
    { id: 'saints',  label: 'Saints',  icon: 'saints' },
    { id: 'me',      label: 'Me',      icon: 'me' },
  ];
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      paddingBottom: 28, paddingTop: 8,
      background: dark ? 'rgba(20,18,26,0.85)' : 'rgba(250,246,240,0.88)',
      backdropFilter: 'blur(20px) saturate(160%)', WebkitBackdropFilter: 'blur(20px) saturate(160%)',
      borderTop: `0.5px solid ${dark ? t.hairline.dark : t.hairline.light}`,
      display: 'flex', justifyContent: 'space-around', zIndex: 30,
    }}>
      {items.map(it => {
        const isActive = active === it.id;
        const fg = isActive
          ? (dark ? '#fff' : t.roseDeep)
          : (dark ? t.inkMute.dark : t.inkMute.light);
        return (
          <button key={it.id} onClick={() => onChange(it.id)} style={{
            background: 'none', border: 'none', cursor: 'pointer',
            padding: '4px 12px', display: 'flex', flexDirection: 'column',
            alignItems: 'center', gap: 3, color: fg,
            fontFamily: 'inherit',
          }}>
            <TabIcon name={it.icon} active={isActive} />
            <span style={{ fontSize: 10, fontWeight: 600, letterSpacing: 0.1 }}>{it.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function TabIcon({ name, active }) {
  const stroke = 'currentColor';
  const fill = active ? 'currentColor' : 'none';
  const sw = 1.8;
  if (name === 'home') return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <path d="M3 11l8-7 8 7v8a1 1 0 01-1 1h-4v-6h-6v6H4a1 1 0 01-1-1v-8z" stroke={stroke} strokeWidth={sw} fill={active ? 'currentColor' : 'none'} fillOpacity={active ? 0.18 : 0} strokeLinejoin="round"/>
    </svg>
  );
  if (name === 'journey') return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <path d="M4 4c4 0 4 14 8 14s4-14 8-14" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
      <circle cx="4" cy="4" r="2" fill={active ? stroke : 'none'} stroke={stroke} strokeWidth={sw}/>
      <circle cx="20" cy="4" r="2" fill={active ? stroke : 'none'} stroke={stroke} strokeWidth={sw}/>
    </svg>
  );
  if (name === 'saints') return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <path d="M11 2l2.6 5.3 5.9.85-4.25 4.15 1 5.85L11 15.4l-5.25 2.75 1-5.85L2.5 8.15l5.9-.85L11 2z" stroke={stroke} strokeWidth={sw} strokeLinejoin="round" fill={active ? stroke : 'none'} fillOpacity={active ? 0.18 : 0}/>
    </svg>
  );
  if (name === 'me') return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <circle cx="11" cy="8" r="3.5" stroke={stroke} strokeWidth={sw} fill={active ? stroke : 'none'} fillOpacity={active ? 0.18 : 0}/>
      <path d="M4 19c1.5-3.5 4-5 7-5s5.5 1.5 7 5" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
    </svg>
  );
  return null;
}

// Subtle decorative cross (small, used sparingly)
function CrossGlyph({ size = 12, color = 'currentColor', opacity = 0.5 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 12 12" style={{ opacity }}>
      <rect x="5.2" y="1" width="1.6" height="10" rx="0.4" fill={color}/>
      <rect x="2" y="4.2" width="8" height="1.6" rx="0.4" fill={color}/>
    </svg>
  );
}

window.SaintPlaceholder = SaintPlaceholder;
window.LiturgicalDot = LiturgicalDot;
window.Chip = Chip;
window.TabBar = TabBar;
window.CrossGlyph = CrossGlyph;

// ─────────────── SIZE GLYPH ───────────────
// Tiny soft SVG illustrations for each weekly size comparison.
// All glyphs sit in a 24×24 box, centered, with stroke-based outlines so they read
// as quiet line drawings rather than emoji. The `palette` prop tints them.
function SizeGlyph({ glyph = 'poppy', size = 28, palette }) {
  const t = window.TOKENS;
  const c = palette || { stem: t.sage, body: t.rose, deep: t.roseDeep, gold: t.gold };

  const G = {
    // Seeds & tiny things — round/oval with a single stem mark
    poppy:      <g><circle cx="12" cy="13" r="2" fill={c.deep}/></g>,
    sesame:     <g><ellipse cx="12" cy="13" rx="2.2" ry="1.4" fill={c.gold}/></g>,
    mustard:    <g><circle cx="12" cy="13" r="2.5" fill={c.gold}/><circle cx="11" cy="12" r="0.6" fill="rgba(255,255,255,0.5)"/></g>,
    appleseed:  <g><path d="M12 10 c-2 0-3 2-3 4 c0 2 1 3 3 3 c2 0 3-1 3-3 c0-2-1-4-3-4z" fill={c.deep}/></g>,
    pea:        <g><circle cx="9" cy="13" r="2.5" fill={c.stem}/><circle cx="13" cy="13" r="2.5" fill={c.stem}/><circle cx="11" cy="11" r="2.5" fill={c.stem}/></g>,

    // Berries / small fruit
    blueberry:  <g><circle cx="12" cy="13" r="4.5" fill="#7B92B5"/><path d="M10 9 l1.5 1.5 l1.5 -1.5" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/><circle cx="10.5" cy="12" r="0.8" fill="rgba(255,255,255,0.4)"/></g>,
    raspberry:  <g><circle cx="10" cy="12" r="1.8" fill={c.deep}/><circle cx="14" cy="12" r="1.8" fill={c.deep}/><circle cx="10" cy="15" r="1.8" fill={c.deep}/><circle cx="14" cy="15" r="1.8" fill={c.deep}/><circle cx="12" cy="13.5" r="1.8" fill={c.deep}/><path d="M11 8 l1 2 l1 -2" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    cherry:     <g><circle cx="9" cy="15" r="3" fill={c.deep}/><circle cx="15" cy="15" r="3" fill={c.deep}/><path d="M9 12 c0 -3 3 -5 6 -5" stroke={c.stem} strokeWidth="1.3" fill="none" strokeLinecap="round"/></g>,
    olive:      <g><ellipse cx="12" cy="13" rx="3" ry="5" fill="#9CAA75"/><path d="M11 7 l1 2 l1 -2" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    fig:        <g><path d="M12 7 c-4 0 -5 4 -5 7 c0 3 2 5 5 5 c3 0 5 -2 5 -5 c0 -3 -1 -7 -5 -7z" fill="#9D6F8C"/><path d="M11 7 l1 -2 l1 2" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    lime:       <g><circle cx="12" cy="13" r="5" fill="#A8B870"/><path d="M11 7 l1 1.5 l1 -1.5" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/><path d="M9 13 l6 0 M12 10 l0 6" stroke="rgba(255,255,255,0.35)" strokeWidth="0.6"/></g>,
    lemon:      <g><ellipse cx="12" cy="13" rx="4" ry="5" fill="#E5C76B"/><circle cx="12" cy="9" r="0.8" fill={c.stem}/><circle cx="12" cy="17" r="0.8" fill={c.stem}/></g>,
    peach:      <g><circle cx="11" cy="14" r="4" fill="#E8A88C"/><circle cx="13" cy="14" r="4" fill="#EAB39A"/><path d="M12 9 c-1 -2 1 -3 2 -2" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    apple:      <g><path d="M12 9 c-3 0 -5 2 -5 5 c0 3 2 5 5 5 c3 0 5 -2 5 -5 c0 -3 -2 -5 -5 -5z" fill="#C66464"/><path d="M12 9 c0 -1 1 -2 2 -2" stroke={c.stem} strokeWidth="1.3" fill="none" strokeLinecap="round"/><path d="M11 11 c0 -1 1 -1 1.5 -1" stroke="rgba(255,255,255,0.4)" strokeWidth="0.8" fill="none" strokeLinecap="round"/></g>,
    avocado:    <g><path d="M12 7 c-3 0 -4 3 -4 6 c0 4 2 6 4 6 c2 0 4 -2 4 -6 c0 -3 -1 -6 -4 -6z" fill="#7E9C5E"/><circle cx="12" cy="14" r="1.6" fill="#5A4530"/></g>,
    pomegranate:<g><circle cx="12" cy="14" r="5" fill="#B45656"/><path d="M11 8 l0 2 l-1 1 M13 8 l0 2 l1 1 M12 8 l0 2.5" stroke={c.stem} strokeWidth="1" fill="none" strokeLinecap="round"/></g>,
    pepper:     <g><path d="M12 9 c-3 0 -4 3 -4 6 c0 3 2 4 4 4 c2 0 4 -1 4 -4 c0 -3 -1 -6 -4 -6z" fill="#C8585A"/><path d="M11 9 l0 -2 l-1 -1 M13 9 l0 -2 l1 -1" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    mango:      <g><path d="M9 11 c0 -3 2 -5 5 -5 c2 0 4 2 4 4 c0 3 -3 6 -6 6 c-2 0 -3 -1 -3 -2.5 c0 -1 0 -1.5 0 -2.5z" fill="#E8A858"/></g>,
    banana:     <g><path d="M6 14 c0 -4 4 -8 9 -8 c1 0 2 0 2 1 c0 0 -1 1 -2 2 c-3 2 -5 4 -7 6 c-1 1 -2 0 -2 -1z" fill="#E8C76B"/></g>,
    carrot:     <g><path d="M9 8 l3 11 l3 -11 z" fill="#D88B4A"/><path d="M10 8 l-1 -2 M12 8 l0 -2 M14 8 l1 -2" stroke={c.stem} strokeWidth="1.4" fill="none" strokeLinecap="round"/></g>,
    squash:     <g><ellipse cx="12" cy="14" rx="3" ry="5" fill="#E5BD6A"/><path d="M12 9 l0 -2" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    corn:       <g><ellipse cx="12" cy="14" rx="3" ry="5" fill="#EBD278"/><path d="M10 11 l4 0 M10 13 l4 0 M10 15 l4 0" stroke="rgba(120,90,40,0.4)" strokeWidth="0.6"/><path d="M9 9 c1 -1 3 -1 4 0 M15 9 c-1 -1 -3 -1 -4 0" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    rutabaga:   <g><path d="M12 9 c-3 0 -5 2 -5 5 c0 3 2 5 5 5 c3 0 5 -2 5 -5 c0 -3 -2 -5 -5 -5z" fill="#C9A878"/><path d="M11 9 l0 -2 M13 9 l0 -2" stroke={c.stem} strokeWidth="1.3" fill="none" strokeLinecap="round"/></g>,
    scallion:   <g><path d="M12 6 l0 13" stroke="#A8B89A" strokeWidth="3" strokeLinecap="round"/><circle cx="12" cy="18" r="2" fill="#F0E8D0"/></g>,
    cauliflower:<g><circle cx="10" cy="12" r="2.5" fill="#F0E8D8"/><circle cx="14" cy="12" r="2.5" fill="#F0E8D8"/><circle cx="12" cy="14" r="2.5" fill="#F0E8D8"/><path d="M9 16 l6 0" stroke={c.stem} strokeWidth="1.4" strokeLinecap="round"/></g>,
    aubergine:  <g><path d="M9 11 c0 -3 2 -5 4 -5 c2 0 4 2 4 5 c0 4 -2 7 -4 7 c-2 0 -4 -3 -4 -7z" fill="#7C5A88"/><path d="M11 7 l0 -2 l-1 -1 M13 7 l0 -2 l1 -1" stroke={c.stem} strokeWidth="1.2" fill="none" strokeLinecap="round"/></g>,
    butternut:  <g><circle cx="12" cy="16" r="3" fill="#E0AA6A"/><path d="M12 6 c0 4 0 7 0 10" stroke="#E0AA6A" strokeWidth="3.5" strokeLinecap="round"/><path d="M12 6 l0 -1" stroke={c.stem} strokeWidth="1.4" strokeLinecap="round"/></g>,
    cabbage:    <g><circle cx="12" cy="13" r="6" fill="#A8C490"/><path d="M8 11 c2 -1 4 -1 4 0 M16 11 c-2 -1 -4 -1 -4 0 M9 14 c2 0 4 0 6 0 M11 9 c0 0 1 -1 2 0" stroke="rgba(80,110,60,0.4)" strokeWidth="0.7" fill="none" strokeLinecap="round"/></g>,
    coconut:    <g><circle cx="12" cy="13" r="5" fill="#7C5A45"/><circle cx="10.5" cy="11" r="0.8" fill="#3A2820"/><circle cx="13.5" cy="11" r="0.8" fill="#3A2820"/><circle cx="12" cy="13" r="0.8" fill="#3A2820"/></g>,
    jicama:     <g><circle cx="12" cy="14" r="5" fill="#D4B890"/><path d="M11 9 l0 -2 M13 9 l0 -2" stroke={c.stem} strokeWidth="1.3" fill="none" strokeLinecap="round"/></g>,
    pineapple:  <g><path d="M9 11 c0 -2 1 -4 3 -4 c2 0 3 2 3 4 c0 4 -1 8 -3 8 c-2 0 -3 -4 -3 -8z" fill="#E5BD5A"/><path d="M10 11 l4 0 M10 13 l4 0 M10 15 l4 0" stroke="rgba(120,90,30,0.5)" strokeWidth="0.6"/><path d="M11 7 l0 -3 M12 7 l0 -4 M13 7 l0 -3" stroke="#A8B89A" strokeWidth="1.4" strokeLinecap="round"/></g>,
    cantaloupe: <g><circle cx="12" cy="13" r="5.5" fill="#E0B58A"/><path d="M7 12 c5 0 10 0 10 0 M8 15 c4 0 8 0 8 0 M9 9 c3 0 6 0 6 0" stroke="rgba(180,130,80,0.4)" strokeWidth="0.6"/></g>,
    honeydew:   <g><circle cx="12" cy="13" r="5.5" fill="#C9D89C"/><path d="M9 11 c2 -1 4 -1 6 0 M9 14 c2 1 4 1 6 0" stroke="rgba(100,130,80,0.3)" strokeWidth="0.5"/></g>,
    romaine:    <g><path d="M12 6 c-3 1 -4 4 -3 7 l0 5 l6 0 l0 -5 c1 -3 0 -6 -3 -7z" fill="#9CC078"/><path d="M12 7 l0 11" stroke="rgba(80,110,60,0.5)" strokeWidth="0.7"/></g>,
    chard:      <g><path d="M11 18 l0 -10 c0 -2 -2 -3 -2 -3 M13 18 l0 -10 c0 -2 2 -3 2 -3" stroke="#C84A4A" strokeWidth="1.6" fill="none" strokeLinecap="round"/><path d="M9 8 c2 -3 4 -4 6 -4 c1 2 1 4 0 6 c-2 2 -4 2 -6 0z" fill="#7E9C5E"/></g>,
    leek:       <g><path d="M12 5 l0 14" stroke="#9CB87C" strokeWidth="3" strokeLinecap="round"/><path d="M12 19 l-1 1 M12 19 l1 1" stroke="#F0E8D0" strokeWidth="2" strokeLinecap="round"/></g>,
    pumpkin:    <g><ellipse cx="9" cy="14" rx="2.5" ry="4" fill="#D88848"/><ellipse cx="12" cy="14" rx="2.5" ry="4.5" fill="#E89858"/><ellipse cx="15" cy="14" rx="2.5" ry="4" fill="#D88848"/><path d="M12 9 l0 -2 c0 -1 1 -1 1 -1" stroke={c.stem} strokeWidth="1.3" fill="none" strokeLinecap="round"/></g>,
    watermelon: <g><circle cx="12" cy="13" r="6" fill="#7CAE5C"/><circle cx="12" cy="13" r="4.5" fill="#E26A6A"/><circle cx="11" cy="12" r="0.5" fill="#3A2520"/><circle cx="13" cy="14" r="0.5" fill="#3A2520"/><circle cx="13" cy="11" r="0.5" fill="#3A2520"/><circle cx="11" cy="14" r="0.5" fill="#3A2520"/></g>,
  };

  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ display: 'block', flexShrink: 0 }}>
      {G[glyph] || G.poppy}
    </svg>
  );
}

// Format size as a short label, e.g. "13 mm" or "1.6 kg"
function formatSize(size) {
  if (!size) return '';
  const parts = [];
  if (size.mm != null) {
    parts.push(size.mm < 10 ? `${size.mm} mm` : size.mm < 100 ? `${size.mm} mm` : `${(size.mm / 10).toFixed(1)} cm`);
  }
  if (size.g != null) {
    parts.push(size.g < 1000 ? `${size.g} g` : `${(size.g / 1000).toFixed(2)} kg`);
  }
  return parts.join(' · ');
}

window.SizeGlyph = SizeGlyph;
window.formatSize = formatSize;
