// accumulation.jsx — the 3 growing motifs: Map / Jar / Booklet
// Each takes progress 0..1 (+ mine/theirs counts) and "grows" as data accumulates.
const { useMemo: _useMemo } = React;

/* keyframes now live in index.html's static <style> (runtime-injected ones
   don't reliably apply in this preview) */

/* seeded rng */
function mulberry(seed) {
  let t = seed + 0x6D2B79F5;
  return function () {
    t |= 0; t = (t + 0x6D2B79F5) | 0;
    let r = Math.imul(t ^ (t >>> 15), 1 | t);
    r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;
    return ((r ^ (r >>> 14)) >>> 0) / 4294967296;
  };
}

function motifMessage(motif, p) {
  const sets = {
    map: ['ふたりの旅の輪郭は、まだこれから', 'ぽつぽつと灯りが点きはじめました', 'ふたりの旅の輪郭が見えてきた', 'そろそろプランを描けそうです'],
    jar: ['想いのかけらが、少しずつ', 'いい感じに積もってきました', 'そろそろブレンドできそうです', '瓶がいっぱい。ブレンドの準備OK'],
    booklet: ['白いページは、ここから', '少しずつ書き込まれています', 'しおりが完成に近づいています', 'しおりが、もうすぐ仕上がります'],
  };
  const arr = sets[motif] || sets.map;
  return p < 0.25 ? arr[0] : p < 0.55 ? arr[1] : p < 0.85 ? arr[2] : arr[3];
}

const ME_C = 'oklch(0.66 0.066 18)';
const PT_C = 'oklch(0.69 0.052 150)';

/* ════════════════════ MAP ════════════════════ */
const MAP_PINS = [
  { x: 88,  y: 96,  who: 'me' },
  { x: 196, y: 78,  who: 'pt' },
  { x: 142, y: 150, who: 'pt' },
  { x: 234, y: 168, who: 'me' },
  { x: 70,  y: 196, who: 'me' },
  { x: 178, y: 214, who: 'pt' },
  { x: 116, y: 246, who: 'me' },
  { x: 250, y: 250, who: 'pt' },
  { x: 44,  y: 132, who: 'me' },
];

function MapBase({ dim = 0 }) {
  return (
    <g>
      <rect x="0" y="0" width="300" height="300" fill="#efe7d8" />
      {/* parks (sage) */}
      <ellipse cx="120" cy="150" rx="58" ry="46" fill="oklch(0.86 0.03 150)" opacity="0.8" />
      <ellipse cx="250" cy="92"  rx="40" ry="34" fill="oklch(0.87 0.028 150)" opacity="0.7" />
      <ellipse cx="232" cy="252" rx="46" ry="38" fill="oklch(0.86 0.03 150)" opacity="0.7" />
      {/* water ribbon */}
      <path d="M-10 232 C 60 210, 110 268, 180 240 S 320 250, 330 222 L 330 320 L -10 320 Z"
            fill="oklch(0.84 0.035 235)" opacity="0.55" />
      {/* roads */}
      <g stroke="#fbf7ef" strokeWidth="7" strokeLinecap="round" opacity="0.9">
        <path d="M-10 110 L 320 70" />
        <path d="M40 -10 L 90 320" />
        <path d="M200 -10 L 250 320" />
        <path d="M-10 200 L 320 178" />
      </g>
      <g stroke="#e6dcca" strokeWidth="2.5" strokeLinecap="round">
        <path d="M-10 110 L 320 70" />
        <path d="M40 -10 L 90 320" />
        <path d="M200 -10 L 250 320" />
      </g>
      {/* dim overlay */}
      {dim > 0.01 && <rect x="0" y="0" width="300" height="300" fill="oklch(0.32 0.03 280)" opacity={dim} />}
    </g>
  );
}

function MapMotif({ progress = 0.5, interactive = false }) {
  const total = MAP_PINS.length;
  const lit = Math.max(0, Math.round(progress * total));
  const dim = (1 - progress) * 0.5 + 0.02;
  return (
    <svg viewBox="0 0 300 300" width="100%" height="100%" style={{ display: 'block', borderRadius: 22 }}>
      <defs>
        <radialGradient id="halo" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="#fff" stopOpacity="0.9" />
          <stop offset="100%" stopColor="#fff" stopOpacity="0" />
        </radialGradient>
      </defs>
      <MapBase dim={dim} />
      {/* route between lit pins */}
      {lit > 1 && (
        <path
          d={MAP_PINS.slice(0, lit).map((p, i) => `${i ? 'L' : 'M'} ${p.x} ${p.y}`).join(' ')}
          fill="none" stroke="oklch(0.72 0.05 60)" strokeWidth="2.4"
          strokeDasharray="2 7" strokeLinecap="round" opacity={Math.min(1, progress * 1.3)} />
      )}
      {/* pins */}
      {MAP_PINS.map((p, i) => {
        const on = i < lit;
        const c = p.who === 'me' ? ME_C : PT_C;
        return (
          <g key={i} style={{ transformOrigin: `${p.x}px ${p.y}px`,
            animation: on ? `pinpop .5s ${i * 0.06}s both` : 'none' }}>
            {on && <circle cx={p.x} cy={p.y} r="22" fill="url(#halo)"
              style={{ animation: 'glowpulse 3.4s ease-in-out infinite' }} />}
            <circle cx={p.x} cy={p.y} r={on ? 6.5 : 3.5}
              fill={on ? c : '#cdbfa8'} opacity={on ? 1 : 0.5}
              stroke={on ? '#fff' : 'none'} strokeWidth="2" />
            {on && <circle cx={p.x} cy={p.y} r="2.4" fill="#fff" opacity="0.9" />}
          </g>
        );
      })}
    </svg>
  );
}

/* ════════════════════ JAR ════════════════════ */
function JarMotif({ progress = 0.5, mine = 6, theirs = 5 }) {
  const rng = mulberry(7);
  const totalKakera = 30;
  const count = Math.round(progress * totalKakera);
  // distribute by mine/theirs ratio
  const ratio = (mine + theirs) > 0 ? mine / (mine + theirs) : 0.5;
  const kakera = _useMemo(() => {
    const arr = [];
    const innerX0 = 96, innerX1 = 204, floor = 250, ceil = 250 - 150 * progress;
    for (let i = 0; i < count; i++) {
      const r = mulberry(i * 99 + 3);
      const x = innerX0 + 6 + r() * (innerX1 - innerX0 - 12);
      const y = floor - r() * (floor - ceil);
      const mn = (i / Math.max(1, count)) < ratio ? (r() > 0.5) : (r() > 0.5);
      arr.push({ x, y, c: r() < ratio ? ME_C : PT_C, s: 5 + r() * 4, rot: r() * 60 - 30 });
    }
    return arr;
  }, [count, progress, ratio]);

  const fillTop = 250 - 150 * progress;
  return (
    <svg viewBox="0 0 300 300" width="100%" height="100%" style={{ display: 'block' }}>
      <defs>
        <clipPath id="jarclip">
          <path d="M96 92 Q96 84 104 84 L196 84 Q204 84 204 92 L204 246 Q204 258 192 258 L108 258 Q96 258 96 246 Z" />
        </clipPath>
        <linearGradient id="jarliquid" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="oklch(0.9 0.04 60)" stopOpacity="0.6" />
          <stop offset="100%" stopColor="oklch(0.85 0.05 30)" stopOpacity="0.35" />
        </linearGradient>
      </defs>
      {/* lid */}
      <rect x="110" y="62" width="80" height="22" rx="8" fill="oklch(0.7 0.05 60)" />
      <rect x="118" y="56" width="64" height="12" rx="6" fill="oklch(0.76 0.045 60)" />
      {/* glass body */}
      <path d="M96 92 Q96 84 104 84 L196 84 Q204 84 204 92 L204 246 Q204 258 192 258 L108 258 Q96 258 96 246 Z"
            fill="oklch(0.97 0.006 230)" opacity="0.55" stroke="oklch(0.8 0.012 230)" strokeWidth="2.5" />
      {/* contents */}
      <g clipPath="url(#jarclip)">
        <rect x="90" y={fillTop} width="120" height="200" fill="url(#jarliquid)" />
        {kakera.map((k, i) => (
          <g key={i} style={{ transformOrigin: `${k.x}px ${k.y}px`, animation: `floatup .5s ${Math.min(i * 0.03, 1)}s both` }}>
            <ellipse cx={k.x} cy={k.y} rx={k.s} ry={k.s * 0.78} fill={k.c}
              opacity="0.92" transform={`rotate(${k.rot} ${k.x} ${k.y})`} />
            <ellipse cx={k.x - k.s * 0.3} cy={k.y - k.s * 0.3} rx={k.s * 0.3} ry={k.s * 0.22} fill="#fff" opacity="0.5" />
          </g>
        ))}
      </g>
      {/* glass shine */}
      <path d="M112 96 L112 244" stroke="#fff" strokeWidth="5" strokeLinecap="round" opacity="0.4" />
    </svg>
  );
}

/* ════════════════════ BOOKLET ════════════════════ */
function wavy(x0, y, len, seed) {
  const r = mulberry(seed);
  let d = `M ${x0} ${y}`;
  const steps = Math.max(2, Math.round(len / 14));
  let x = x0;
  for (let i = 0; i < steps; i++) {
    const dx = len / steps;
    const cy = y + (r() * 6 - 3);
    d += ` q ${dx / 2} ${cy - y} ${dx} 0`;
    x += dx;
  }
  return d;
}

function BookletMotif({ progress = 0.5, mine = 6, theirs = 5 }) {
  const lines = 9;
  const filled = Math.round(progress * lines);
  const ratio = (mine + theirs) > 0 ? mine / (mine + theirs) : 0.5;
  return (
    <svg viewBox="0 0 300 300" width="100%" height="100%" style={{ display: 'block' }}>
      {/* page shadow + paper */}
      <rect x="58" y="46" width="190" height="210" rx="8" fill="oklch(0.78 0.02 60)" opacity="0.25" transform="translate(5 6)" />
      <rect x="58" y="46" width="190" height="210" rx="8" fill="#fcf8f0" stroke="oklch(0.85 0.02 60)" strokeWidth="1.5" />
      {/* ruled lines */}
      {Array.from({ length: lines }).map((_, i) => (
        <line key={'r' + i} x1="78" x2="228" y1={78 + i * 20} y2={78 + i * 20}
          stroke="oklch(0.9 0.015 60)" strokeWidth="1" />
      ))}
      {/* handwriting */}
      {Array.from({ length: filled }).map((_, i) => {
        const r = mulberry(i * 41 + 5);
        const y = 73 + i * 20;
        const len = 90 + r() * 60;
        const c = r() < ratio ? ME_C : PT_C;
        const d = wavy(80, y, len, i * 7 + 2);
        return (
          <path key={'h' + i} d={d} fill="none" stroke={c} strokeWidth="2.2"
            strokeLinecap="round" opacity="0.85"
            style={{ animation: `floatup .5s ${i * 0.07}s both` }} />
        );
      })}
      {/* doodles appear later */}
      {progress > 0.5 && (
        <g style={{ animation: 'risefade .6s both' }}>
          <path d="M210 168 c -4 -7 -14 -4 -14 3 c 0 6 8 10 14 14 c 6 -4 14 -8 14 -14 c 0 -7 -10 -10 -14 -3 z"
            fill="none" stroke={ME_C} strokeWidth="2" opacity="0.7" />
        </g>
      )}
      {progress > 0.75 && (
        <g style={{ animation: 'risefade .6s both' }}>
          <path d="M90 232 l 4 8 l 8 1 l -6 6 l 2 8 l -8 -4 l -8 4 l 2 -8 l -6 -6 l 8 -1 z"
            fill="none" stroke={PT_C} strokeWidth="1.8" opacity="0.7" />
        </g>
      )}
      {/* ribbon bookmark */}
      <path d="M222 46 L222 96 L214 86 L206 96 L206 46 Z" fill={ME_C} opacity="0.85" />
    </svg>
  );
}

/* unified picker */
function Motif({ kind = 'map', progress = 0.5, mine = 6, theirs = 5 }) {
  if (kind === 'jar') return <JarMotif progress={progress} mine={mine} theirs={theirs} />;
  if (kind === 'booklet') return <BookletMotif progress={progress} mine={mine} theirs={theirs} />;
  return <MapMotif progress={progress} />;
}

/* tiny indicator for home cards — a growing arc + motif glyph */
function MotifMini({ kind = 'map', progress = 0.5, size = 56 }) {
  const R = 25, C = 2 * Math.PI * R;
  return (
    <div style={{ position: 'relative', width: size, height: size, flexShrink: 0 }}>
      <svg width={size} height={size} viewBox="0 0 60 60" style={{ transform: 'rotate(-90deg)' }}>
        <circle cx="30" cy="30" r={R} fill="none" stroke="var(--line-2)" strokeWidth="4" />
        <circle cx="30" cy="30" r={R} fill="none" stroke="var(--amethyst)" strokeWidth="4"
          strokeLinecap="round" strokeDasharray={C} strokeDashoffset={C * (1 - progress)}
          style={{ transition: 'stroke-dashoffset .6s ease' }} />
      </svg>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 22,
      }}>
        <MotifGlyph kind={kind} />
      </div>
    </div>
  );
}

function MotifGlyph({ kind, size = 26 }) {
  const c = 'var(--amethyst)';
  if (kind === 'jar') return (
    <svg width={size} height={size} viewBox="0 0 24 24"><path d="M8 4h8M9 4v2.5L8 8v10a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V8l-1-1.5V4" fill="none" stroke={c} strokeWidth="1.6"/><path d="M8.5 14h7" stroke={c} strokeWidth="1.6" strokeLinecap="round"/></svg>
  );
  if (kind === 'booklet') return (
    <svg width={size} height={size} viewBox="0 0 24 24"><rect x="6" y="4" width="12" height="16" rx="2" fill="none" stroke={c} strokeWidth="1.6"/><path d="M9 9h6M9 12h6M9 15h4" stroke={c} strokeWidth="1.5" strokeLinecap="round"/></svg>
  );
  return (
    <svg width={size} height={size} viewBox="0 0 24 24"><path d="M9 4 4 6v14l5-2 6 2 5-2V4l-5 2-6-2Z" fill="none" stroke={c} strokeWidth="1.6" strokeLinejoin="round"/><circle cx="10" cy="11" r="1.4" fill={c}/></svg>
  );
}

Object.assign(window, { Motif, MapMotif, JarMotif, BookletMotif, MapBase, MotifMini, MotifGlyph, motifMessage, mulberry, ME_C, PT_C, MAP_PINS });
