// Rasterizes the CardPreview SVG to bitmap bytes. The SVG is serialized and
// loaded through an <img>, so every resource it needs (fonts, photos, flag)
// must be inline data URLs — CardPreview guarantees that. Fonts are awaited
// before drawing so glyphs never rasterize with a fallback face.

// rasterizeCard returns base64 image bytes (no data: prefix).
// type 'image/jpeg' targets e-mail (maxBytes enforced by stepping quality
// down); 'image/png' is used for template thumbnails.
export async function rasterizeCard(
  svgEl: SVGSVGElement,
  outW: number,
  outH: number,
  type: 'image/jpeg' | 'image/png',
  maxBytes = 800 * 1024,
): Promise<string> {
  await document.fonts.ready;

  const clone = svgEl.cloneNode(true) as SVGSVGElement;
  clone.setAttribute('width', String(outW));
  clone.setAttribute('height', String(outH));
  clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  const xml = new XMLSerializer().serializeToString(clone);
  const url = URL.createObjectURL(new Blob([xml], { type: 'image/svg+xml;charset=utf-8' }));
  try {
    const img = new Image();
    img.src = url;
    await img.decode();

    const canvas = document.createElement('canvas');
    canvas.width = outW;
    canvas.height = outH;
    const ctx = canvas.getContext('2d');
    if (!ctx) throw new Error('canvas 2d context unavailable');
    if (type === 'image/jpeg') {
      ctx.fillStyle = '#ffffff'; // JPEG has no alpha — avoid black background
      ctx.fillRect(0, 0, outW, outH);
    }
    ctx.drawImage(img, 0, 0, outW, outH);

    if (type === 'image/png') {
      return canvas.toDataURL('image/png').split(',')[1];
    }
    // Step the JPEG quality down until the e-mail size target is met.
    for (const q of [0.9, 0.8, 0.7, 0.6]) {
      const b64 = canvas.toDataURL('image/jpeg', q).split(',')[1];
      if (b64.length * 0.75 <= maxBytes) return b64;
    }
    return canvas.toDataURL('image/jpeg', 0.5).split(',')[1];
  } finally {
    URL.revokeObjectURL(url);
  }
}
