/**
 * Pure composite helpers — flatten a layer list into a single canvas
 * for thumbnails / merged-mask use.
 *
 * Both helpers are stateless: the caller passes everything they need
 * (layer list, canvas dimensions, an offsets lookup). The legacy
 * gallery editor's module-level functions wrap these with their own
 * state.
 */

/**
 * Cheap downscaled preview composited from all visible layers.
 * Returns a JPEG dataURL, or null when there's nothing to draw.
 *
 * @param {Array<{visible: boolean, opacity: number, id: string, canvas: HTMLCanvasElement}>} layers
 * @param {number} imgW            Document width in canvas pixels.
 * @param {number} imgH            Document height in canvas pixels.
 * @param {Map<string,{x:number,y:number}>} offsets  Layer offsets, keyed by id.
 * @param {number} maxDim          Longest-edge target in CSS pixels.
 * @param {number} quality         JPEG quality 0..1.
 * @returns {string|null}
 */
export function buildThumbnail(layers, imgW, imgH, offsets, maxDim, quality = 0.6) {
  if (!imgW || !imgH) return null;
  try {
    const scale = Math.min(1, maxDim / Math.max(imgW, imgH));
    const tw = Math.max(1, Math.round(imgW * scale));
    const th = Math.max(1, Math.round(imgH * scale));
    const c = document.createElement('canvas');
    c.width = tw; c.height = th;
    const ctx = c.getContext('2d');
    for (const layer of layers) {
      if (!layer.visible) continue;
      ctx.globalAlpha = layer.opacity;
      const off = offsets.get(layer.id) || { x: 0, y: 0 };
      ctx.drawImage(
        layer.canvas,
        off.x * scale, off.y * scale,
        layer.canvas.width * scale, layer.canvas.height * scale,
      );
    }
    ctx.globalAlpha = 1;
    return c.toDataURL('image/jpeg', quality);
  } catch (_) {
    return null;
  }
}


/**
 * Union of every visible mask sub-layer across `layers`, rendered as a
 * binary white canvas the size of the document.
 *
 * `lighter` composite = additive — overlapping pixels stay clamped at
 * 255, so wherever any mask painted, the result is solid white.
 * Returns null when no mask layer contributed any pixels (so the caller
 * can early-out cleanly).
 *
 * @param {Array<{masks?: Array<{visible: boolean, canvas: HTMLCanvasElement}>}>} layers
 * @param {number} imgW
 * @param {number} imgH
 * @returns {HTMLCanvasElement|null}
 */
export function buildMergedMaskCanvas(layers, imgW, imgH) {
  if (!imgW || !imgH) return null;
  const out = document.createElement('canvas');
  out.width = imgW;
  out.height = imgH;
  const ctx = out.getContext('2d');
  ctx.globalCompositeOperation = 'lighter';
  let anyMask = false;
  for (const ly of layers) {
    if (!ly.masks || !ly.masks.length) continue;
    for (const mk of ly.masks) {
      if (!mk.visible) continue;
      if (!mk.canvas || !mk.canvas.width || !mk.canvas.height) continue;
      ctx.drawImage(mk.canvas, 0, 0);
      anyMask = true;
    }
  }
  ctx.globalCompositeOperation = 'source-over';
  return anyMask ? out : null;
}
