// creatures.jsx — the living wallet companion. CSS-rendered, no assets.
// <Creature hue size stage art mood bob accessory />  art: clay|pixel|gem|flat
// Exports to window: Creature, CreatureEgg, palFromHue

function palFromHue(hue) {
  return {
    glow:  `oklch(0.92 0.09 ${hue})`,
    light: `oklch(0.88 0.12 ${hue})`,
    base:  `oklch(0.78 0.165 ${hue})`,
    dark:  `oklch(0.64 0.17 ${hue})`,
    deep:  `oklch(0.52 0.15 ${hue})`,
    ink:   `oklch(0.34 0.10 ${hue})`,
  };
}

// blob silhouette varies subtly with evolution stage
const BLOB_SHAPE = {
  1: '58% 42% 56% 44% / 60% 58% 42% 40%',
  2: '54% 46% 52% 48% / 56% 54% 46% 44%',
  3: '50% 50% 48% 52% / 52% 56% 44% 48%',
};

// ── eyes shared across clay & flat ──────────────────────────────
function Eyes({ size, mood, ink, flat }) {
  const ew = size * 0.15, eh = size * (mood === 'sleepy' ? 0.04 : 0.185);
  const gap = size * 0.18, top = size * 0.40;
  const eye = (dx) => (
    <div style={{
      position: 'absolute', top, left: `calc(50% + ${dx}px)`,
      transform: 'translateX(-50%)',
      width: ew, height: eh, borderRadius: '50%',
      background: flat ? ink : '#FFFFFF',
      boxShadow: flat ? 'none' : '0 1px 2px rgba(0,0,0,0.12)',
      overflow: 'hidden',
    }}>
      {!flat && mood !== 'sleepy' && (
        <div style={{
          position: 'absolute', top: '22%', left: '20%',
          width: '62%', height: '62%', borderRadius: '50%', background: ink,
        }}>
          <div style={{ position: 'absolute', top: '12%', left: '14%', width: '38%', height: '38%', borderRadius: '50%', background: 'rgba(255,255,255,0.95)' }} />
        </div>
      )}
      {flat && (
        <div style={{ position: 'absolute', top: '16%', left: '20%', width: '30%', height: '30%', borderRadius: '50%', background: 'rgba(255,255,255,0.9)' }} />
      )}
    </div>
  );
  return <>{eye(-gap)}{eye(gap)}</>;
}

function Cheeks({ size, top }) {
  const cw = size * 0.13, off = size * 0.30;
  const c = (dx) => (
    <div style={{
      position: 'absolute', top, left: `calc(50% + ${dx}px)`, transform: 'translateX(-50%)',
      width: cw, height: cw * 0.7, borderRadius: '50%',
      background: 'radial-gradient(circle, rgba(255,120,150,0.55), rgba(255,120,150,0))',
    }} />
  );
  return <>{c(-off)}{c(off)}</>;
}

function Mouth({ size, top, mood, ink }) {
  if (mood === 'sleepy') return null;
  const w = size * (mood === 'excited' ? 0.16 : 0.12);
  return (
    <div style={{
      position: 'absolute', top, left: '50%', transform: 'translateX(-50%)',
      width: w, height: w * (mood === 'excited' ? 0.9 : 0.55),
      borderRadius: mood === 'excited' ? '0 0 50% 50% / 0 0 100% 100%' : '0 0 60% 60%',
      background: mood === 'excited' ? ink : 'transparent',
      borderBottom: mood === 'excited' ? 'none' : `${Math.max(2, size * 0.022)}px solid ${ink}`,
      opacity: 0.85,
    }} />
  );
}

// ── CLAY (default soft-3D) ──────────────────────────────────────
function ClayBody({ size, stage, hue, mood, accessory }) {
  const p = palFromHue(hue);
  const feet = stage >= 2;
  const crest = stage >= 2;
  const horn = stage >= 3;
  return (
    <>
      {feet && [-1, 1].map((s) => (
        <div key={s} style={{
          position: 'absolute', bottom: size * 0.01, left: `calc(50% + ${s * size * 0.18}px)`,
          transform: 'translateX(-50%)', width: size * 0.17, height: size * 0.12,
          borderRadius: '50%', background: `radial-gradient(circle at 40% 30%, ${p.base}, ${p.deep})`,
          boxShadow: `inset 0 -2px 3px ${p.deep}`, zIndex: 1,
        }} />
      ))}
      {crest && (
        <div style={{
          position: 'absolute', top: -size * 0.06, left: '50%', transform: 'translateX(-50%) rotate(-4deg)',
          width: size * 0.14, height: size * 0.20, borderRadius: '60% 60% 40% 40%',
          background: `linear-gradient(160deg, ${p.light}, ${p.dark})`, zIndex: 0,
        }} />
      )}
      {horn && (
        <div style={{
          position: 'absolute', top: -size * 0.14, left: '50%', transform: 'translateX(-50%)',
          width: size * 0.10, height: size * 0.16, borderRadius: '50% 50% 50% 50% / 70% 70% 30% 30%',
          background: `linear-gradient(180deg, ${p.glow}, ${p.dark})`, zIndex: 0,
          boxShadow: `0 0 ${size * 0.08}px ${p.light}`,
        }} />
      )}
      {/* body */}
      <div style={{
        position: 'absolute', inset: `${size * 0.06}px ${size * 0.05}px ${feet ? size * 0.07 : size * 0.04}px`,
        borderRadius: BLOB_SHAPE[stage],
        background: `radial-gradient(circle at 34% 26%, ${p.glow} 0%, ${p.base} 46%, ${p.dark} 88%, ${p.deep} 100%)`,
        boxShadow: `inset ${size * 0.06}px ${size * 0.07}px ${size * 0.1}px rgba(255,255,255,0.45), inset -${size * 0.05}px -${size * 0.08}px ${size * 0.1}px ${p.deep}`,
        zIndex: 2,
      }}>
        {/* top sheen */}
        <div style={{
          position: 'absolute', top: '10%', left: '22%', width: '34%', height: '26%',
          borderRadius: '50%', background: 'radial-gradient(circle, rgba(255,255,255,0.85), rgba(255,255,255,0))',
          filter: 'blur(1px)',
        }} />
        <Eyes size={size} mood={mood} ink={p.ink} />
        <Cheeks size={size} top={size * 0.56} />
        <Mouth size={size} top={size * 0.60} mood={mood} ink={p.ink} />
      </div>
      {accessory === 'crown' && (
        <div style={{ position: 'absolute', top: -size * 0.02, left: '50%', transform: 'translateX(-50%)', fontSize: size * 0.22, zIndex: 5 }}>👑</div>
      )}
    </>
  );
}

// ── FLAT (vector cartoon) ───────────────────────────────────────
function FlatBody({ size, stage, hue, mood }) {
  const p = palFromHue(hue);
  return (
    <div style={{
      position: 'absolute', inset: `${size * 0.06}px ${size * 0.05}px ${size * 0.05}px`,
      borderRadius: BLOB_SHAPE[stage], background: p.base,
      boxShadow: `inset 0 0 0 ${Math.max(3, size * 0.03)}px ${p.deep}`,
      zIndex: 2,
    }}>
      <div style={{ position: 'absolute', top: '14%', left: '24%', width: '28%', height: '20%', borderRadius: '50%', background: p.light, opacity: 0.7 }} />
      <Eyes size={size} mood={mood} ink={p.ink} flat />
      <Cheeks size={size} top={size * 0.56} />
      <Mouth size={size} top={size * 0.60} mood={mood} ink={p.ink} />
    </div>
  );
}

// ── GEM (faceted) ───────────────────────────────────────────────
function GemBody({ size, hue, mood }) {
  const p = palFromHue(hue);
  const ink = p.ink;
  return (
    <div style={{ position: 'absolute', inset: size * 0.06, zIndex: 2 }}>
      <div style={{
        position: 'absolute', inset: 0,
        clipPath: 'polygon(50% 0%, 92% 26%, 100% 70%, 50% 100%, 0% 70%, 8% 26%)',
        background: `conic-gradient(from 200deg, ${p.dark}, ${p.light}, ${p.base}, ${p.deep}, ${p.light}, ${p.dark})`,
        filter: `drop-shadow(0 ${size * 0.04}px ${size * 0.06}px ${p.deep}66)`,
      }} />
      <div style={{
        position: 'absolute', inset: 0,
        clipPath: 'polygon(50% 0%, 92% 26%, 50% 40%, 8% 26%)',
        background: `linear-gradient(180deg, ${p.glow}, ${p.light})`, opacity: 0.9,
      }} />
      <div style={{
        position: 'absolute', inset: 0,
        clipPath: 'polygon(8% 26%, 50% 40%, 50% 100%, 0% 70%)',
        background: p.dark, opacity: 0.5,
      }} />
      <div style={{ position: 'absolute', top: '12%', left: '30%', width: '14%', height: '10%', background: 'rgba(255,255,255,0.85)', transform: 'rotate(20deg)' }} />
      <Eyes size={size} mood={mood} ink={ink} />
      <Mouth size={size} top={size * 0.58} mood={mood} ink={ink} />
    </div>
  );
}

// ── PIXEL (sprite) ──────────────────────────────────────────────
const PIXEL_MAP = [
  '....DDDDDD....',
  '..DDBBBBBBDD..',
  '.DBBBBBBBBBBD.',
  'DBBBBBBBBBBBBD',
  'DBBLLBBBBLLBBD',
  'DBBLKBBBBLKBBD',
  'DBBBBBBBBBBBBD',
  'DBCBBBBBBBBCBD',
  'DBBBBKKKKBBBBD',
  '.DBBBBBBBBBBD.',
  '..DDBBBBBBDD..',
  '....DDDDDD....',
];
function PixelBody({ size, hue }) {
  const p = palFromHue(hue);
  const cols = PIXEL_MAP[0].length, rows = PIXEL_MAP.length;
  const colorFor = (ch) => ({
    B: p.base, D: p.deep, L: '#FFFFFF', K: '#221c2e',
    C: 'rgba(255,120,150,0.85)',
  }[ch] || 'transparent');
  return (
    <div style={{
      position: 'absolute', inset: size * 0.08,
      display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gridTemplateRows: `repeat(${rows}, 1fr)`,
      imageRendering: 'pixelated', zIndex: 2,
      filter: `drop-shadow(0 ${size * 0.03}px 0 ${p.deep})`,
    }}>
      {PIXEL_MAP.flatMap((row, r) => row.split('').map((ch, c) => (
        <div key={`${r}-${c}`} style={{ background: colorFor(ch) }} />
      )))}
    </div>
  );
}

function Creature({ hue = 300, size = 160, stage = 1, art = 'clay', mood = 'happy', bob = true, accessory = null, style = {} }) {
  const p = palFromHue(hue);
  const Body = { clay: ClayBody, flat: FlatBody, gem: GemBody, pixel: PixelBody }[art] || ClayBody;
  return (
    <div style={{ width: size, height: size, position: 'relative', ...style }}>
      {/* contact shadow */}
      <div style={{
        position: 'absolute', bottom: -size * 0.01, left: '50%', transform: 'translateX(-50%)',
        width: size * 0.6, height: size * 0.1, borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(40,30,60,0.20), rgba(40,30,60,0))',
        animation: bob ? 'poke-shadow 3.4s ease-in-out infinite' : 'none',
      }} />
      <div style={{ position: 'absolute', inset: 0, animation: bob ? 'poke-bob 3.4s ease-in-out infinite' : 'none' }}>
        <Body size={size} stage={stage} hue={hue} mood={mood} accessory={accessory} />
      </div>
    </div>
  );
}

// ── EGG (onboarding hatch) ──────────────────────────────────────
function CreatureEgg({ hue = 300, size = 200, cracked = 0, wobble = true }) {
  const p = palFromHue(hue);
  return (
    <div style={{ width: size, height: size * 1.18, position: 'relative', animation: wobble ? 'poke-wobble 2.6s ease-in-out infinite' : 'none' }}>
      <div style={{
        position: 'absolute', inset: 0, borderRadius: '50% 50% 48% 52% / 60% 60% 40% 40%',
        background: `radial-gradient(circle at 34% 26%, ${p.glow}, ${p.base} 55%, ${p.dark} 100%)`,
        boxShadow: `inset ${size * 0.06}px ${size * 0.07}px ${size * 0.1}px rgba(255,255,255,0.5), inset -${size * 0.05}px -${size * 0.08}px ${size * 0.1}px ${p.deep}`,
      }}>
        {/* speckles */}
        {[[30, 28, 0.1], [62, 40, 0.08], [44, 62, 0.12], [70, 70, 0.07], [26, 55, 0.06]].map(([l, t, s], i) => (
          <div key={i} style={{ position: 'absolute', left: `${l}%`, top: `${t}%`, width: size * s, height: size * s, borderRadius: '50%', background: p.glow, opacity: 0.6 }} />
        ))}
        <div style={{ position: 'absolute', top: '12%', left: '24%', width: '28%', height: '22%', borderRadius: '50%', background: 'radial-gradient(circle, rgba(255,255,255,0.8), transparent)' }} />
        {cracked > 0 && (
          <div style={{
            position: 'absolute', top: '46%', left: 0, right: 0, height: 3,
            background: `repeating-linear-gradient(90deg, transparent 0 6px, ${p.deep} 6px 9px)`,
            clipPath: 'polygon(0 40%, 12% 0, 26% 70%, 40% 10%, 55% 80%, 70% 20%, 84% 70%, 100% 30%, 100% 100%, 0 100%)',
            opacity: cracked,
          }} />
        )}
      </div>
    </div>
  );
}

Object.assign(window, { Creature, CreatureEgg, palFromHue });
