// share.jsx — "A mind, observed": a shareable poster artifact from a Witness sitting.
// Built as a single SVG so what you see is exactly what exports to PNG.

function mtShapeSVG(s, attrs, capColor) {
  if (s.t === 'ell') return `<ellipse cx="${s.cx}" cy="${s.cy}" rx="${s.rx}" ry="${s.ry}" ${attrs}/>`;
  if (s.t === 'rr') return `<rect x="${s.x}" y="${s.y}" width="${s.w}" height="${s.h}" rx="${s.r}" ${attrs}/>`;
  if (s.t === 'cap') return `<line x1="${s.x1}" y1="${s.y1}" x2="${s.x2}" y2="${s.y2}" stroke="${capColor}" stroke-width="${s.w}" stroke-linecap="round" fill="none"/>`;
  return '';
}

function mtWrap(text, max) {
  const words = text.split(' '); const lines = []; let cur = '';
  words.forEach(w => {
    if ((cur + ' ' + w).trim().length > max) { lines.push(cur.trim()); cur = w; }
    else cur += ' ' + w;
  });
  if (cur.trim()) lines.push(cur.trim());
  return lines;
}

function esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }

// data: { pose, phenoms:[{hue,lx,ly,kind}], arose, noted, quote:{t,a}, dateLabel }
function buildWitnessShareSVG(data) {
  const W = 1080, H = 1920;
  const P = mtPose(data.pose);
  const [, , vw, vh] = P.vb;
  // body placement box
  const bw = 760, bx = (W - bw) / 2, scale = bw / vw, bh = vh * scale, by = 470;
  const tx = bx, ty = by;

  // body shapes
  const bodyFill = 'rgba(54,232,210,0.08)', bodyStroke = 'rgba(54,232,210,0.42)', capCol = 'rgba(54,232,210,0.16)';
  let body = '';
  P.regions.forEach(r => {
    const isHead = r.id === P.headId;
    if (r.shape.t === 'cap') body += mtShapeSVG(r.shape, '', capCol);
    else body += mtShapeSVG(r.shape, `fill="${isHead ? 'rgba(120,205,255,0.5)' : bodyFill}" stroke="${isHead ? 'rgba(140,210,255,0.7)' : bodyStroke}" stroke-width="1.4"`);
  });

  // phenomena dots (in pose coords)
  let dots = '';
  (data.phenoms || []).slice(0, 16).forEach(p => {
    const x = (p.lx / 100) * vw, y = (p.ly / 100) * vh;
    const rr = p.kind === 'body' ? 11 : 8;
    dots += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${rr * 2.4}" fill="${p.hue}" opacity="0.16"/>`;
    dots += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${rr}" fill="${p.hue}"/>`;
    dots += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${rr + 3}" fill="none" stroke="${p.hue}" stroke-opacity="0.55" stroke-width="1.4"/>`;
  });

  const quoteLines = data.quote ? mtWrap('“' + data.quote.t + '”', 38) : [];
  const qY = 1600;
  const quoteSVG = quoteLines.map((ln, i) =>
    `<text x="${W / 2}" y="${qY + i * 50}" text-anchor="middle" font-family="Georgia, serif" font-style="italic" font-size="36" fill="rgba(206,233,230,0.82)">${esc(ln)}</text>`
  ).join('');

  return `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">
  <defs>
    <radialGradient id="bg" cx="50%" cy="26%" r="80%">
      <stop offset="0%" stop-color="#0c2230"/><stop offset="55%" stop-color="#06121d"/><stop offset="100%" stop-color="#03080e"/>
    </radialGradient>
    <radialGradient id="aura" cx="50%" cy="44%" r="55%">
      <stop offset="0%" stop-color="rgba(86,180,255,0.28)"/><stop offset="50%" stop-color="rgba(54,232,210,0.07)"/><stop offset="100%" stop-color="rgba(54,232,210,0)"/>
    </radialGradient>
  </defs>
  <rect width="${W}" height="${H}" fill="url(#bg)"/>
  <ellipse cx="${W / 2}" cy="${by + bh * 0.42}" rx="520" ry="640" fill="url(#aura)"/>

  <text x="${W / 2}" y="150" text-anchor="middle" font-family="'Courier New', monospace" font-size="26" letter-spacing="9" fill="#36E8D2">A N I C C A</text>
  <text x="${W / 2}" y="262" text-anchor="middle" font-family="Georgia, serif" font-size="86" fill="#EAF7F4">A mind, observed</text>
  <text x="${W / 2}" y="320" text-anchor="middle" font-family="Georgia, serif" font-style="italic" font-size="32" fill="rgba(206,233,230,0.6)">${esc(data.dateLabel || 'a sitting witnessed')}</text>

  <g transform="translate(${tx},${ty}) scale(${scale})">
    ${body}
    ${dots}
  </g>

  <line x1="200" y1="1410" x2="${W - 200}" y2="1410" stroke="rgba(120,210,205,0.18)" stroke-width="1"/>
  <text x="${W / 2 - 150}" y="1490" text-anchor="middle" font-family="'Courier New', monospace" font-size="78" fill="#36E8D2">${data.arose}</text>
  <text x="${W / 2 - 150}" y="1534" text-anchor="middle" font-family="Georgia, serif" font-size="28" fill="rgba(206,233,230,0.55)">arose</text>
  <text x="${W / 2 + 150}" y="1490" text-anchor="middle" font-family="'Courier New', monospace" font-size="78" fill="#7CF0DC">${data.noted}</text>
  <text x="${W / 2 + 150}" y="1534" text-anchor="middle" font-family="Georgia, serif" font-size="28" fill="rgba(206,233,230,0.55)">noted &amp; released</text>

  ${quoteSVG}
  ${data.quote ? `<text x="${W / 2}" y="${qY + quoteLines.length * 50 + 34}" text-anchor="middle" font-family="'Courier New', monospace" font-size="24" letter-spacing="2" fill="rgba(206,233,230,0.5)">— ${esc(data.quote.a.toUpperCase())}</text>` : ''}

  <text x="${W / 2}" y="${H - 70}" text-anchor="middle" font-family="Georgia, serif" font-style="italic" font-size="28" fill="rgba(206,233,230,0.4)">everything that arises, passes</text>
</svg>`;
}

// SVG string → PNG Blob
function svgToPngBlob(svg, w, h) {
  return new Promise((resolve, reject) => {
    const blob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const img = new Image();
    img.onload = () => {
      const cv = document.createElement('canvas'); cv.width = w; cv.height = h;
      const ctx = cv.getContext('2d'); ctx.drawImage(img, 0, 0, w, h);
      URL.revokeObjectURL(url);
      cv.toBlob(b => b ? resolve(b) : reject(new Error('toBlob failed')), 'image/png');
    };
    img.onerror = (e) => { URL.revokeObjectURL(url); reject(e); };
    img.src = url;
  });
}

function ShareCard({ data, onClose }) {
  const C = MT_COLORS;
  const svg = React.useMemo(() => buildWitnessShareSVG(data), [data]);
  const dataUrl = React.useMemo(() => 'data:image/svg+xml;utf8,' + encodeURIComponent(svg), [svg]);
  const [status, setStatus] = React.useState('');

  async function getBlob() { return svgToPngBlob(svg, 1080, 1920); }

  async function onSave() {
    try {
      setStatus('Rendering…');
      const blob = await getBlob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url; a.download = 'anicca-a-mind-observed.png';
      document.body.appendChild(a); a.click(); a.remove();
      setTimeout(() => URL.revokeObjectURL(url), 4000);
      setStatus('Saved ✓');
    } catch (e) { setStatus('Save unavailable here'); }
  }

  async function onShare() {
    try {
      const blob = await getBlob();
      const file = new File([blob], 'anicca-a-mind-observed.png', { type: 'image/png' });
      if (navigator.canShare && navigator.canShare({ files: [file] })) {
        await navigator.share({ files: [file], title: 'A mind, observed', text: 'A sitting, witnessed — via Anicca.' });
        setStatus('Shared ✓');
      } else { onSave(); }
    } catch (e) { setStatus(''); }
  }

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 60, background: 'rgba(2,6,11,0.86)', backdropFilter: 'blur(8px)',
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '24px 20px' }}>
      <div style={{ flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }}>
        <img src={dataUrl} alt="A mind, observed — shareable poster" style={{ maxHeight: '100%', maxWidth: '100%', width: 'auto',
          borderRadius: 18, border: `1px solid ${C.tealLine}`, boxShadow: '0 20px 70px rgba(0,0,0,0.6)' }} />
      </div>
      <div style={{ flexShrink: 0, paddingTop: 18, width: '100%', maxWidth: 420 }}>
        {status && <div style={{ textAlign: 'center', fontSize: 13, color: C.teal, marginBottom: 12, fontFamily: 'var(--mono)' }}>{status}</div>}
        <div style={{ display: 'flex', gap: 10 }}>
          <MTButton full onClick={onShare}><MTIcon name="spark" size={18} color="#022019" /> Share</MTButton>
          <MTButton full tone="ghost" onClick={onSave}>Save image</MTButton>
        </div>
        <button onClick={onClose} style={{ appearance: 'none', background: 'none', border: 'none', color: C.inkFaint, cursor: 'pointer', marginTop: 14, fontSize: 14, width: '100%', fontFamily: 'var(--sans)' }}>Close</button>
      </div>
    </div>
  );
}

Object.assign(window, { buildWitnessShareSVG, svgToPngBlob, ShareCard });
