
// Character illustration library — humans and robots
// Exported to window for use across script tags

const HUMAN_CONFIGS = [
  // Human 1 — woman, teal top, brown skin
  {
    skin: '#8D5524', hair: '#2C1A0E', hairStyle: 'bun',
    top: '#2A7F8C', topStyle: 'crew', pants: '#1B3A6B', shoes: '#333'
  },
  // Human 2 — man, navy shirt, light skin
  {
    skin: '#FDBCB4', hair: '#3B2314', hairStyle: 'short',
    top: '#1B3A6B', topStyle: 'collar', pants: '#4A4A4A', shoes: '#222'
  },
  // Human 3 — woman, gold blouse, medium skin
  {
    skin: '#C68642', hair: '#1A1A1A', hairStyle: 'long',
    top: '#B8860B', topStyle: 'crew', pants: '#2A7F8C', shoes: '#555'
  },
  // Human 4 — man, teal polo, dark skin
  {
    skin: '#4A2912', hair: '#1A0A00', hairStyle: 'afro',
    top: '#2A7F8C', topStyle: 'polo', pants: '#333', shoes: '#111'
  },
  // Human 5 — woman, white blouse, light-medium skin
  {
    skin: '#E8B88A', hair: '#5C3317', hairStyle: 'ponytail',
    top: '#F2F4F6', topStyle: 'crew', pants: '#1B3A6B', shoes: '#222'
  },
  // Human 6 — man, gold sweater, medium-light skin
  {
    skin: '#D4956A', hair: '#4A2912', hairStyle: 'short',
    top: '#B8860B', topStyle: 'crew', pants: '#2A2A2A', shoes: '#333'
  },
  // Human 7 — woman, navy blazer, medium skin
  {
    skin: '#C68642', hair: '#1A1A1A', hairStyle: 'bob',
    top: '#1B3A6B', topStyle: 'collar', pants: '#4A4A4A', shoes: '#111'
  },
  // Human 8 — non-binary, teal jacket, light skin
  {
    skin: '#FFDFC4', hair: '#D4956A', hairStyle: 'medium',
    top: '#2A7F8C', topStyle: 'crew', pants: '#1B3A6B', shoes: '#444'
  },
];

const ROBOT_CONFIGS = [
  // Robot 1 — classic boxy, teal
  { body: '#2A7F8C', head: '#1B3A6B', accent: '#B8860B', style: 'boxy', eyes: 'round' },
  // Robot 2 — rounded friendly, gold
  { body: '#B8860B', head: '#2A7F8C', accent: '#1B3A6B', style: 'rounded', eyes: 'visor' },
  // Robot 3 — tall slim, navy
  { body: '#1B3A6B', head: '#2A7F8C', accent: '#B8860B', style: 'slim', eyes: 'square' },
  // Robot 4 — chunky, teal-dark
  { body: '#1A5F6A', head: '#B8860B', accent: '#2A7F8C', style: 'chunky', eyes: 'dot' },
  // Robot 5 — sleek, gold-dark
  { body: '#8A6200', head: '#1B3A6B', accent: '#2A7F8C', style: 'sleek', eyes: 'round' },
  // Robot 6 — orb-head, navy-dark
  { body: '#0F2548', head: '#2A7F8C', accent: '#B8860B', style: 'orb', eyes: 'visor' },
];

function HairStyle({ style, color, skin }) {
  switch (style) {
    case 'bun':
      return <>
        <ellipse cx="50" cy="22" rx="14" ry="12" fill={color} />
        <circle cx="50" cy="10" r="6" fill={color} />
      </>;
    case 'short':
      return <ellipse cx="50" cy="20" rx="15" ry="10" fill={color} />;
    case 'long':
      return <>
        <ellipse cx="50" cy="20" rx="14" ry="11" fill={color} />
        <rect x="36" y="26" width="6" height="22" rx="3" fill={color} />
        <rect x="58" y="26" width="6" height="22" rx="3" fill={color} />
      </>;
    case 'afro':
      return <ellipse cx="50" cy="18" rx="18" ry="16" fill={color} />;
    case 'ponytail':
      return <>
        <ellipse cx="50" cy="20" rx="14" ry="10" fill={color} />
        <rect x="60" y="16" width="5" height="18" rx="2" fill={color} />
      </>;
    case 'bob':
      return <>
        <ellipse cx="50" cy="20" rx="15" ry="11" fill={color} />
        <rect x="35" y="24" width="6" height="12" rx="3" fill={color} />
        <rect x="59" y="24" width="6" height="12" rx="3" fill={color} />
      </>;
    case 'medium':
      return <>
        <ellipse cx="50" cy="20" rx="14" ry="11" fill={color} />
        <rect x="36" y="26" width="5" height="14" rx="2" fill={color} />
        <rect x="59" y="26" width="5" height="14" rx="2" fill={color} />
      </>;
    default:
      return <ellipse cx="50" cy="20" rx="14" ry="10" fill={color} />;
  }
}

function TopStyle({ style, color, skin }) {
  const collar = style === 'collar' || style === 'polo';
  return <>
    {/* Torso */}
    <rect x="34" y="55" width="32" height="26" rx="4" fill={color} />
    {/* Arms */}
    <rect x="20" y="56" width="14" height="8" rx="4" fill={color} />
    <rect x="66" y="56" width="14" height="8" rx="4" fill={color} />
    {/* Hands */}
    <circle cx="17" cy="64" r="5" fill={skin} />
    <circle cx="83" cy="64" r="5" fill={skin} />
    {collar && (
      <>
        <polygon points="50,56 44,60 50,65 56,60" fill="white" opacity="0.4" />
      </>
    )}
  </>;
}

function HumanFigure({ config, scale = 1, onClick, style: outerStyle }) {
  const { skin, hair, hairStyle, top, topStyle, pants, shoes } = config;
  const w = 100 * scale;
  const h = 140 * scale;

  return (
    <svg
      width={w} height={h}
      viewBox="0 0 100 140"
      style={{ cursor: onClick ? 'pointer' : 'default', ...outerStyle }}
      onClick={onClick}
    >
      {/* Shadow */}
      <ellipse cx="50" cy="136" rx="22" ry="4" fill="rgba(0,0,0,0.12)" />
      {/* Hair (behind head) */}
      <HairStyle style={hairStyle} color={hair} skin={skin} />
      {/* Head */}
      <ellipse cx="50" cy="30" rx="13" ry="15" fill={skin} />
      {/* Eyes */}
      <circle cx="45" cy="27" r="2" fill="#333" />
      <circle cx="55" cy="27" r="2" fill="#333" />
      {/* Smile */}
      <path d="M 44 34 Q 50 38 56 34" stroke="#555" strokeWidth="1.5" fill="none" strokeLinecap="round" />
      {/* Neck */}
      <rect x="45" y="43" width="10" height="12" rx="3" fill={skin} />
      {/* Top & Arms */}
      <TopStyle style={topStyle} color={top} skin={skin} />
      {/* Pants */}
      <rect x="35" y="78" width="13" height="30" rx="3" fill={pants} />
      <rect x="52" y="78" width="13" height="30" rx="3" fill={pants} />
      {/* Shoes */}
      <ellipse cx="41" cy="111" rx="9" ry="5" fill={shoes} />
      <ellipse cx="59" cy="111" rx="9" ry="5" fill={shoes} />
    </svg>
  );
}

function RobotEyes({ style, color }) {
  switch (style) {
    case 'round':
      return <>
        <circle cx="43" cy="30" r="5" fill={color} />
        <circle cx="57" cy="30" r="5" fill={color} />
        <circle cx="43" cy="30" r="2" fill="white" />
        <circle cx="57" cy="30" r="2" fill="white" />
      </>;
    case 'visor':
      return <rect x="36" y="26" width="28" height="8" rx="4" fill={color} opacity="0.9" />;
    case 'square':
      return <>
        <rect x="38" y="26" width="8" height="8" rx="1" fill={color} />
        <rect x="54" y="26" width="8" height="8" rx="1" fill={color} />
      </>;
    case 'dot':
      return <>
        <circle cx="43" cy="30" r="3" fill={color} />
        <circle cx="57" cy="30" r="3" fill={color} />
      </>;
    default:
      return <>
        <circle cx="43" cy="30" r="4" fill={color} />
        <circle cx="57" cy="30" r="4" fill={color} />
      </>;
  }
}

function RobotBody({ style, body, head, accent }) {
  switch (style) {
    case 'boxy':
      return <>
        {/* Head */}
        <rect x="30" y="14" width="40" height="32" rx="4" fill={head} />
        <RobotEyes style="round" color={accent} />
        {/* Antenna */}
        <rect x="48" y="6" width="4" height="10" rx="2" fill={head} />
        <circle cx="50" cy="5" r="4" fill={accent} />
        {/* Neck */}
        <rect x="44" y="44" width="12" height="8" rx="2" fill={head} />
        {/* Body */}
        <rect x="28" y="52" width="44" height="30" rx="5" fill={body} />
        {/* Chest panel */}
        <rect x="36" y="58" width="28" height="14" rx="3" fill={head} opacity="0.5" />
        <circle cx="44" cy="65" r="3" fill={accent} />
        <circle cx="56" cy="65" r="3" fill={accent} />
        {/* Arms */}
        <rect x="14" y="54" width="14" height="8" rx="4" fill={body} />
        <rect x="72" y="54" width="14" height="8" rx="4" fill={body} />
        {/* Hands */}
        <rect x="10" y="60" width="10" height="8" rx="3" fill={head} />
        <rect x="80" y="60" width="10" height="8" rx="3" fill={head} />
        {/* Legs */}
        <rect x="33" y="82" width="13" height="26" rx="3" fill={body} />
        <rect x="54" y="82" width="13" height="26" rx="3" fill={body} />
        {/* Feet */}
        <rect x="30" y="105" width="18" height="8" rx="3" fill={head} />
        <rect x="52" y="105" width="18" height="8" rx="3" fill={head} />
      </>;
    case 'rounded':
      return <>
        {/* Head */}
        <ellipse cx="50" cy="28" rx="20" ry="18" fill={head} />
        <RobotEyes style="visor" color={accent} />
        {/* Antenna */}
        <rect x="48" y="8" width="4" height="12" rx="2" fill={head} />
        <ellipse cx="50" cy="7" rx="5" ry="3" fill={accent} />
        {/* Neck */}
        <rect x="44" y="44" width="12" height="8" rx="4" fill={head} />
        {/* Body */}
        <rect x="30" y="52" width="40" height="28" rx="8" fill={body} />
        <circle cx="50" cy="66" r="8" fill={head} opacity="0.5" />
        <circle cx="50" cy="66" r="4" fill={accent} />
        {/* Arms */}
        <ellipse cx="18" cy="60" rx="8" ry="6" fill={body} />
        <ellipse cx="82" cy="60" rx="8" ry="6" fill={body} />
        {/* Hands */}
        <circle cx="11" cy="64" r="5" fill={head} />
        <circle cx="89" cy="64" r="5" fill={head} />
        {/* Legs */}
        <rect x="34" y="80" width="12" height="24" rx="4" fill={body} />
        <rect x="54" y="80" width="12" height="24" rx="4" fill={body} />
        {/* Feet */}
        <ellipse cx="40" cy="106" rx="10" ry="6" fill={head} />
        <ellipse cx="60" cy="106" rx="10" ry="6" fill={head} />
      </>;
    case 'slim':
      return <>
        {/* Head */}
        <rect x="34" y="12" width="32" height="28" rx="6" fill={head} />
        <RobotEyes style="square" color={accent} />
        {/* Antenna */}
        <rect x="47" y="4" width="6" height="10" rx="3" fill={accent} />
        {/* Neck */}
        <rect x="45" y="40" width="10" height="10" rx="2" fill={head} />
        {/* Body */}
        <rect x="34" y="50" width="32" height="32" rx="4" fill={body} />
        <rect x="40" y="56" width="20" height="14" rx="2" fill={head} opacity="0.4" />
        <rect x="44" y="60" width="4" height="6" rx="1" fill={accent} />
        <rect x="52" y="60" width="4" height="6" rx="1" fill={accent} />
        {/* Arms */}
        <rect x="18" y="52" width="16" height="7" rx="3" fill={body} />
        <rect x="66" y="52" width="16" height="7" rx="3" fill={body} />
        {/* Hands */}
        <rect x="12" y="57" width="9" height="7" rx="2" fill={head} />
        <rect x="79" y="57" width="9" height="7" rx="2" fill={head} />
        {/* Legs */}
        <rect x="36" y="82" width="11" height="28" rx="3" fill={body} />
        <rect x="53" y="82" width="11" height="28" rx="3" fill={body} />
        {/* Feet */}
        <rect x="33" y="107" width="16" height="7" rx="2" fill={head} />
        <rect x="51" y="107" width="16" height="7" rx="2" fill={head} />
      </>;
    case 'chunky':
      return <>
        {/* Head */}
        <rect x="26" y="10" width="48" height="36" rx="5" fill={head} />
        <RobotEyes style="dot" color={accent} />
        {/* Mouth */}
        <rect x="38" y="37" width="24" height="5" rx="2" fill={accent} opacity="0.7" />
        {/* Antenna */}
        <rect x="47" y="2" width="6" height="10" rx="3" fill={head} />
        <circle cx="50" cy="2" r="4" fill={accent} />
        {/* Neck */}
        <rect x="42" y="46" width="16" height="8" rx="3" fill={head} />
        {/* Body */}
        <rect x="22" y="54" width="56" height="32" rx="6" fill={body} />
        <rect x="32" y="60" width="36" height="16" rx="3" fill={head} opacity="0.4" />
        <circle cx="42" cy="68" r="4" fill={accent} />
        <circle cx="58" cy="68" r="4" fill={accent} />
        {/* Arms */}
        <rect x="6" y="56" width="16" height="10" rx="4" fill={body} />
        <rect x="78" y="56" width="16" height="10" rx="4" fill={body} />
        {/* Hands */}
        <rect x="2" y="62" width="10" height="8" rx="3" fill={head} />
        <rect x="88" y="62" width="10" height="8" rx="3" fill={head} />
        {/* Legs */}
        <rect x="28" y="86" width="18" height="22" rx="4" fill={body} />
        <rect x="54" y="86" width="18" height="22" rx="4" fill={body} />
        {/* Feet */}
        <rect x="24" y="104" width="24" height="9" rx="3" fill={head} />
        <rect x="52" y="104" width="24" height="9" rx="3" fill={head} />
      </>;
    case 'sleek':
      return <>
        {/* Head */}
        <ellipse cx="50" cy="26" rx="16" ry="18" fill={head} />
        <RobotEyes style="round" color={accent} />
        {/* Top fin */}
        <polygon points="50,8 44,16 56,16" fill={accent} />
        {/* Neck */}
        <rect x="45" y="42" width="10" height="9" rx="2" fill={head} />
        {/* Body */}
        <rect x="32" y="51" width="36" height="30" rx="6" fill={body} />
        <ellipse cx="50" cy="66" rx="10" ry="8" fill={head} opacity="0.5" />
        <circle cx="50" cy="66" r="4" fill={accent} />
        {/* Arms */}
        <rect x="18" y="53" width="14" height="7" rx="3" fill={body} />
        <rect x="68" y="53" width="14" height="7" rx="3" fill={body} />
        {/* Hands */}
        <circle cx="14" cy="58" r="5" fill={head} />
        <circle cx="86" cy="58" r="5" fill={head} />
        {/* Legs */}
        <rect x="35" y="81" width="11" height="26" rx="3" fill={body} />
        <rect x="54" y="81" width="11" height="26" rx="3" fill={body} />
        {/* Feet */}
        <ellipse cx="41" cy="109" rx="9" ry="5" fill={head} />
        <ellipse cx="59" cy="109" rx="9" ry="5" fill={head} />
      </>;
    case 'orb':
      return <>
        {/* Head — orb */}
        <circle cx="50" cy="26" r="20" fill={head} />
        <RobotEyes style="visor" color={accent} />
        <circle cx="50" cy="36" r="4" fill={accent} opacity="0.7" />
        {/* Neck */}
        <rect x="44" y="44" width="12" height="8" rx="2" fill={head} />
        {/* Body */}
        <rect x="30" y="52" width="40" height="28" rx="6" fill={body} />
        <rect x="38" y="58" width="24" height="12" rx="3" fill={head} opacity="0.4" />
        <circle cx="44" cy="64" r="3" fill={accent} />
        <circle cx="56" cy="64" r="3" fill={accent} />
        {/* Arms */}
        <rect x="16" y="54" width="14" height="8" rx="4" fill={body} />
        <rect x="70" y="54" width="14" height="8" rx="4" fill={body} />
        {/* Hands */}
        <circle cx="12" cy="60" r="5" fill={head} />
        <circle cx="88" cy="60" r="5" fill={head} />
        {/* Legs */}
        <rect x="34" y="80" width="12" height="24" rx="3" fill={body} />
        <rect x="54" y="80" width="12" height="24" rx="3" fill={body} />
        {/* Feet */}
        <ellipse cx="40" cy="106" rx="10" ry="5" fill={head} />
        <ellipse cx="60" cy="106" rx="10" ry="5" fill={head} />
      </>;
    default:
      return null;
  }
}

function RobotFigure({ config, scale = 1, onClick, style: outerStyle }) {
  const { body, head, accent, style, eyes } = config;
  const w = 100 * scale;
  const h = 140 * scale;

  return (
    <svg
      width={w} height={h}
      viewBox="0 0 100 140"
      style={{ cursor: onClick ? 'pointer' : 'default', ...outerStyle }}
      onClick={onClick}
    >
      {/* Shadow */}
      <ellipse cx="50" cy="136" rx="22" ry="4" fill="rgba(0,0,0,0.15)" />
      <RobotBody style={style} body={body} head={head} accent={accent} />
    </svg>
  );
}

function SpeechBubble({ text, type = 'human', width = 140 }) {
  const isRobot = type === 'robot';
  // Use style-guide colors
  const bg = isRobot ? '#4a7a5c' : '#1a3a4a';
  const borderColor = isRobot ? '#5a9a6e' : '#2a5a7a';

  return (
    <svg
      width={width}
      height={44}
      viewBox={`0 0 ${width} 44`}
      style={{ overflow: 'visible', display: 'block' }}
    >
      {/* Oval balloon body */}
      <ellipse
        cx={width / 2} cy={18}
        rx={width / 2 - 2} ry={15}
        fill={bg}
        stroke={borderColor}
        strokeWidth="1.5"
      />
      {/* Knot at bottom of balloon */}
      <ellipse cx={width / 2} cy={34} rx={3} ry={2.5} fill={bg} stroke={borderColor} strokeWidth="1" />
      {/* String from knot downward */}
      <line x1={width / 2} y1="36.5" x2={width / 2} y2="44" stroke="#8d9e8a" strokeWidth="1.2" />
      {/* Text inside */}
      <text
        x={width / 2} y={20}
        textAnchor="middle"
        dominantBaseline="middle"
        fill="#f0ede7"
        fontSize="9.5"
        fontWeight="600"
        fontFamily="DM Sans, sans-serif"
        style={{ letterSpacing: '0.01em' }}
      >
        {text.length > 22 ? (
          <>
            <tspan x={width / 2} dy="-5">{text.substring(0, Math.ceil(text.length / 2))}</tspan>
            <tspan x={width / 2} dy="11">{text.substring(Math.ceil(text.length / 2))}</tspan>
          </>
        ) : (
          text
        )}
      </text>
    </svg>
  );
}

function StringLine({ height = 60 }) {
  return (
    <div style={{
      width: '2px',
      height: `${height}px`,
      background: 'linear-gradient(to bottom, #8d9e8a 60%, transparent)',
      margin: '0 auto',
      opacity: 0.6,
    }} />
  );
}

// A complete character card with balloon + string to hand + figure
function CharacterCard({ title, subtitle, type = 'human', figureIndex = 0, scale = 0.9, animate = true, delay = 0 }) {
  const [visible, setVisible] = React.useState(!animate);

  React.useEffect(() => {
    if (!animate) return;
    const t = setTimeout(() => setVisible(true), delay);
    return () => clearTimeout(t);
  }, [animate, delay]);

  const config = type === 'human'
    ? HUMAN_CONFIGS[figureIndex % HUMAN_CONFIGS.length]
    : ROBOT_CONFIGS[figureIndex % ROBOT_CONFIGS.length];

  // Cap bubble width at 150px, min 90px
  const bubbleWidth = Math.min(150, Math.max(90, title.length * 7));
  const cardWidth = Math.max(bubbleWidth + 10, 100 * scale + 10);
  // Figure dimensions at scale
  const figW = 100 * scale;
  const figH = 140 * scale;
  // The hand is at approx x=83, y=64 in the 100×140 viewBox → scale it
  // String runs from balloon bottom (centered on cardWidth) to hand position
  const balloonBottomX = cardWidth / 2;
  const handX = (83 / 100) * figW + (cardWidth - figW) / 2;
  const handY = (64 / 140) * figH;
  // String total height: from balloon end (y=44 in bubble svg) to hand
  const stringHeight = 18 + handY; // 18px gap between bubble and figure top, then to hand

  return (
    <div style={{
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      opacity: visible ? 1 : 0,
      transform: visible ? 'translateY(0) scale(1)' : 'translateY(20px) scale(0.8)',
      transition: 'opacity 0.5s ease, transform 0.5s ease',
      width: `${cardWidth}px`,
      position: 'relative',
    }}>
      {/* Balloon */}
      <SpeechBubble text={title} type={type} width={bubbleWidth} />
      {/* SVG string from balloon knot to hand */}
      <svg
        width={cardWidth}
        height={stringHeight}
        style={{ display: 'block', marginTop: '-2px' }}
        overflow="visible"
      >
        {/* Curved string from balloon center-bottom to hand position */}
        <path
          d={`M ${balloonBottomX} 0 Q ${balloonBottomX + 6} ${stringHeight * 0.5} ${handX} ${stringHeight}`}
          stroke="#8d9e8a"
          strokeWidth="1.3"
          fill="none"
          strokeDasharray="3,2"
          opacity="0.7"
        />
      </svg>

      {/* Figure */}
      {type === 'human'
        ? <HumanFigure config={config} scale={scale} style={{ marginTop: `-${handY + 2}px` }} />
        : <RobotFigure config={config} scale={scale} style={{ marginTop: `-${handY + 2}px` }} />
      }

      {/* Subtitle below figure */}
      {subtitle && (
        <div style={{
          fontSize: '9px',
          color: type === 'human' ? '#4a7a5c' : '#c9a96e',
          fontWeight: '500',
          marginTop: '4px',
          textAlign: 'center',
          maxWidth: '130px',
          opacity: 0.85,
          lineHeight: '1.3',
        }}>
          {subtitle}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  HumanFigure,
  RobotFigure,
  CharacterCard,
  SpeechBubble,
  StringLine,
  HUMAN_CONFIGS,
  ROBOT_CONFIGS,
});
