// Shared primitives for Huddle

// ───── Color tokens ─────
const C = {
  coral:       '#FF6B5B',
  coralDeep:   '#E8543F',
  coralSoft:   '#FFD4C2',
  navy:        '#1E2A4A',
  navySoft:    '#334066',
  cream:       '#FBF6EE',
  creamDeep:   '#F3ECDE',
  sage:        '#8AA896',
  sageSoft:    '#C6D5CB',
  ink:         '#2B2318',
  inkMuted:    '#7A6F5E',
  hairline:    'rgba(30,42,74,0.08)',
  white:       '#FFFFFF',
};

// ───── Avatars ─────
function Avatar({ user, size = 28, stacked = false, style = {} }) {
  const common = {
    width: size, height: size, borderRadius: '50%',
    boxShadow: stacked ? `0 0 0 2.5px ${C.cream}` : 'none',
    flexShrink: 0,
    ...style,
  };
  if (user?.avatarUrl) {
    return (
      <img src={user.avatarUrl} alt={user.name || ''} style={{
        ...common, objectFit: 'cover', display: 'block',
      }} onError={(e) => { e.currentTarget.style.display = 'none'; }}/>
    );
  }
  return (
    <div style={{
      ...common,
      background: user?.color || C.inkMuted,
      color: '#fff',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: '"DM Sans", system-ui', fontWeight: 600,
      fontSize: size * 0.42, letterSpacing: 0.2,
    }}>{user?.avatar || '?'}</div>
  );
}

function AvatarStack({ users, size = 24, max = 4 }) {
  const shown = users.slice(0, max);
  const overflow = users.length - shown.length;
  return (
    <div style={{ display: 'flex', alignItems: 'center' }}>
      {shown.map((u, i) => (
        <div key={u.id} style={{ marginLeft: i === 0 ? 0 : -size * 0.32 }}>
          <Avatar user={u} size={size} stacked />
        </div>
      ))}
      {overflow > 0 && (
        <div style={{
          marginLeft: -size * 0.32,
          width: size, height: size, borderRadius: '50%',
          background: C.cream, color: C.navy,
          boxShadow: `0 0 0 2.5px ${C.cream}, inset 0 0 0 1.5px ${C.navy}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: '"DM Sans", system-ui', fontWeight: 600,
          fontSize: size * 0.38,
        }}>+{overflow}</div>
      )}
    </div>
  );
}

// ───── Category pill ─────
function CategoryBadge({ cat, size = 'sm' }) {
  const padding = size === 'sm' ? '4px 9px 4px 8px' : '6px 12px 6px 10px';
  const fontSize = size === 'sm' ? 11.5 : 13;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      background: 'rgba(255,255,255,0.92)',
      color: C.navy,
      padding,
      borderRadius: 999,
      fontFamily: '"DM Sans", system-ui',
      fontWeight: 600, fontSize,
      letterSpacing: -0.1,
      backdropFilter: 'blur(10px)',
      boxShadow: '0 2px 6px rgba(30,42,74,0.08)',
    }}>
      <span style={{ fontSize: fontSize + 1 }}>{cat.emoji}</span>
      {cat.label}
    </span>
  );
}

// ───── Placeholder / image ─────
// Three modes:
//   spec.url        → render an <img> (real photo from xAI extraction or an upload)
//   spec.pattern    → render the SVG item-specific scene
//   spec missing    → neutral coral gradient
function Placeholder({ spec, radius = 0, style = {} }) {
  if (!spec) {
    return (
      <div style={{
        background: `linear-gradient(135deg, ${C.coralSoft}, ${C.coral})`,
        borderRadius: radius, ...style,
      }}/>
    );
  }
  if (spec.url) {
    return (
      <div style={{ overflow: 'hidden', borderRadius: radius, background: C.creamDeep, ...style }}>
        <img src={spec.url} alt=""
             style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
             onError={(e) => { e.currentTarget.style.display = 'none'; }}/>
      </div>
    );
  }
  const { palette = ['#FF6B5B','#FFD4C2','#FBF6EE'], pattern = 'blobs' } = spec;
  const [c1, c2, c3] = palette;
  const patterns = {
    // Sunset Cinema — projector beam + sun
    sunset: (
      <>
        <rect width="100%" height="100%" fill={c1}/>
        <circle cx="50" cy="62" r="22" fill={c2} opacity="0.95"/>
        <rect x="0" y="70" width="100" height="30" fill={c3} opacity="0.45"/>
        <rect x="10" y="80" width="80" height="3" fill={c3} opacity="0.7"/>
        <path d="M46 35 L54 35 L58 48 L42 48 Z" fill={c3} opacity="0.85"/>
      </>
    ),
    // Little Gem — wine glass silhouette
    wineglass: (
      <>
        <rect width="100%" height="100%" fill={c3}/>
        <ellipse cx="30" cy="35" rx="22" ry="16" fill={c1} opacity="0.85"/>
        <ellipse cx="72" cy="70" rx="18" ry="14" fill={c2} opacity="0.9"/>
        {/* wine glass */}
        <path d="M40 34 Q40 50 50 52 Q60 50 60 34 Z" fill={c1} opacity="0.95"/>
        <rect x="49" y="52" width="2" height="18" fill={c1} opacity="0.85"/>
        <rect x="42" y="70" width="16" height="2" rx="1" fill={c1} opacity="0.85"/>
        <ellipse cx="50" cy="38" rx="6" ry="3" fill="#fff" opacity="0.3"/>
      </>
    ),
    // Pottery — stacked bowls / rings
    pottery: (
      <>
        <rect width="100%" height="100%" fill={c2}/>
        <ellipse cx="50" cy="75" rx="34" ry="6" fill={c1} opacity="0.35"/>
        {/* bowl */}
        <path d="M28 50 Q28 72 50 72 Q72 72 72 50 Z" fill={c1} opacity="0.9"/>
        <ellipse cx="50" cy="50" rx="22" ry="5" fill={c3}/>
        <ellipse cx="50" cy="50" rx="18" ry="3.5" fill={c1} opacity="0.7"/>
        {/* small bowl stacked */}
        <path d="M38 28 Q38 42 50 42 Q62 42 62 28 Z" fill={c3} opacity="0.9"/>
        <ellipse cx="50" cy="28" rx="12" ry="3" fill={c1}/>
      </>
    ),
    // Run Club — running track stripes
    track: (
      <>
        <rect width="100%" height="100%" fill={c3}/>
        {[0,1,2,3,4,5].map(i => (
          <rect key={i} x="0" y={i*15+10} width="100" height="7" fill={c1} opacity={0.55 + (i%2)*0.15}/>
        ))}
        {/* sneaker shape */}
        <path d="M18 55 Q18 48 28 48 L58 48 Q70 48 72 55 L72 62 L18 62 Z" fill={c2}/>
        <rect x="20" y="58" width="50" height="2" fill={c3} opacity="0.6"/>
      </>
    ),
    // Mission Trail — peaks with hiker silhouette
    hike: (
      <>
        <rect width="100%" height="100%" fill={c3}/>
        <circle cx="78" cy="22" r="9" fill={c1} opacity="0.5"/>
        <polygon points="0,100 22,45 38,65 58,30 78,55 100,40 100,100" fill={c1} opacity="0.75"/>
        <polygon points="0,100 18,62 36,78 56,55 76,72 100,60 100,100" fill={c2}/>
        {/* tiny hiker */}
        <circle cx="48" cy="68" r="1.8" fill={c3}/>
        <rect x="47" y="70" width="2" height="5" fill={c3}/>
        <path d="M46 75 L48 78 L50 75" stroke={c3} strokeWidth="1" fill="none"/>
        <rect x="50" y="70" width="4" height="1" fill={c3} transform="rotate(20 50 70)"/>
      </>
    ),
    // Japanese Breakfast concert — stage with mic + lights
    concert: (
      <>
        <rect width="100%" height="100%" fill={c2}/>
        {/* stage lights */}
        <path d="M20 0 L10 55 L30 55 Z" fill={c1} opacity="0.45"/>
        <path d="M80 0 L70 55 L90 55 Z" fill={c3} opacity="0.4"/>
        <path d="M50 0 L42 60 L58 60 Z" fill="#fff" opacity="0.25"/>
        {/* crowd silhouettes */}
        <path d="M0 100 L0 82 Q8 78 16 82 Q24 76 32 82 Q40 78 48 82 Q56 76 64 82 Q72 78 80 82 Q88 76 100 82 L100 100 Z" fill={c1}/>
        {/* mic on stand */}
        <circle cx="50" cy="48" r="3.5" fill={c3}/>
        <rect x="49" y="51" width="2" height="22" fill={c3}/>
        <rect x="44" y="73" width="12" height="1.5" fill={c3}/>
      </>
    ),
    // Taxidermy bar — moon + antlers
    taxidermy: (
      <>
        <rect width="100%" height="100%" fill={c1}/>
        <circle cx="72" cy="28" r="13" fill={c3}/>
        <circle cx="68" cy="26" r="11" fill={c1}/>
        {[15,40,60,85,25,55].map((x,i)=>(
          <circle key={i} cx={x} cy={15+i*9} r="0.6" fill={c3}/>
        ))}
        {/* antlers on wall */}
        <path d="M50 70 L50 55 M50 60 L42 52 M50 60 L58 52 M42 52 L38 48 M42 52 L44 46 M58 52 L62 48 M58 52 L56 46" stroke={c3} strokeWidth="1.5" fill="none" strokeLinecap="round"/>
        <path d="M45 70 L55 70" stroke={c3} strokeWidth="2" strokeLinecap="round"/>
      </>
    ),
    // Kindred — pasta plate / swirl
    pasta: (
      <>
        <rect width="100%" height="100%" fill={c3}/>
        <circle cx="50" cy="55" r="32" fill={c2} opacity="0.4"/>
        <circle cx="50" cy="55" r="26" fill="#fff" opacity="0.7"/>
        {/* pasta swirls */}
        {[0,1,2,3,4].map(i => {
          const a = (i/5)*Math.PI*2;
          return <path key={i}
            d={`M${50+Math.cos(a)*15},${55+Math.sin(a)*15} Q${50+Math.cos(a+0.3)*8},${55+Math.sin(a+0.3)*8} ${50+Math.cos(a+0.6)*14},${55+Math.sin(a+0.6)*14}`}
            stroke={c1} strokeWidth="2.5" fill="none" strokeLinecap="round" opacity="0.9"/>;
        })}
        <circle cx="42" cy="48" r="2.5" fill={c1}/>
        <circle cx="58" cy="62" r="2" fill={c1} opacity="0.8"/>
      </>
    ),
    // Ruth Asawa retrospective — sculpture wire looks
    asawa: (
      <>
        <rect width="100%" height="100%" fill={c1}/>
        {/* hanging wire sculptures */}
        {[30, 55, 78].map((cx, i) => (
          <g key={i}>
            <line x1={cx} y1="0" x2={cx} y2="18" stroke={c2} strokeWidth="0.5" opacity="0.6"/>
            {[0,1,2,3].map(j => (
              <ellipse key={j}
                cx={cx} cy={22 + j*14}
                rx={10 - j*1.5} ry={6 - j*0.8}
                fill="none" stroke={c2} strokeWidth="1.2"
                opacity={0.55 + j*0.08}/>
            ))}
          </g>
        ))}
      </>
    ),
    // Priya's bday picnic — blanket + confetti
    picnic: (
      <>
        <rect width="100%" height="100%" fill={c1}/>
        {/* checkered blanket */}
        <g transform="translate(22 55) rotate(-6)">
          {[0,1,2,3].map(r => [0,1,2,3,4].map(col => (
            <rect key={`${r}-${col}`} x={col*12} y={r*10} width="12" height="10"
              fill={(r+col)%2 ? c2 : '#fff'} opacity="0.85"/>
          )))}
        </g>
        {/* confetti above */}
        {Array.from({length: 16}).map((_,i)=>{
          const x = (i*41)%100, y = (i*13)%48;
          const rot = (i*31)%360;
          return <rect key={i} x={x} y={y} width="3" height="1" fill={i%3===0?c3:(i%3===1?c2:'#fff')} transform={`rotate(${rot} ${x} ${y})`}/>;
        })}
      </>
    ),

    // Legacy patterns (kept for back-compat)
    blobs: (<>
      <rect width="100%" height="100%" fill={c3}/>
      <ellipse cx="30" cy="40" rx="38" ry="30" fill={c1} opacity="0.85"/>
      <ellipse cx="70" cy="70" rx="32" ry="25" fill={c2}/>
    </>),
    peaks: (<>
      <rect width="100%" height="100%" fill={c3}/>
      <polygon points="0,100 25,55 45,75 65,40 85,65 100,50 100,100" fill={c1} opacity="0.75"/>
      <polygon points="0,100 20,70 40,85 60,60 80,80 100,70 100,100" fill={c2}/>
    </>),
  };
  return (
    <div style={{ overflow: 'hidden', borderRadius: radius, ...style }}>
      <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style={{ display: 'block' }}>
        <defs>
          <linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor="#000" stopOpacity="0"/>
            <stop offset="1" stopColor="#000" stopOpacity="0.3"/>
          </linearGradient>
        </defs>
        {patterns[pattern] || patterns.blobs}
      </svg>
    </div>
  );
}

// ───── Source favicon dot ─────
function SourceDot({ source }) {
  const map = {
    'instagram.com':  { bg: 'linear-gradient(135deg,#feda75,#fa7e1e,#d62976,#962fbf)', ch: 'ig' },
    'youtube.com':    { bg: '#FF0000', ch: '▶' },
    'eventbrite.com': { bg: '#F05537', ch: 'eb' },
    'resy.com':       { bg: '#000',    ch: 'r'  },
    'sfmoma.org':     { bg: '#000',    ch: 'sf' },
    'alltrails.com':  { bg: '#2A8A3E', ch: 'at' },
    'songkick.com':   { bg: '#F80046', ch: 'sk' },
    'strava.com':     { bg: '#FC4C02', ch: 'st' },
    'mudroom.studio': { bg: '#C58BF2', ch: 'md' },
    'Manual':         { bg: C.navy,    ch: '✎'  },
  };
  const m = map[source] || { bg: C.inkMuted, ch: '•' };
  return (
    <div style={{
      width: 16, height: 16, borderRadius: 4,
      background: m.bg, color: '#fff',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: '"DM Sans", system-ui', fontWeight: 700, fontSize: 8.5,
      flexShrink: 0,
    }}>{m.ch}</div>
  );
}

// ───── Screen shell (cream bg) ─────
function Screen({ children, style = {} }) {
  return (
    <div style={{
      background: C.cream,
      minHeight: '100%',
      paddingBottom: 120,
      ...style,
    }}>{children}</div>
  );
}

// Utility: lookup
const userById = (id) => GROUP.members.find(m => m.id === id);
const catById = (id) => CATEGORIES.find(c => c.id === id);

Object.assign(window, {
  C, Avatar, AvatarStack, CategoryBadge, Placeholder, SourceDot, Screen,
  userById, catById,
});
