/**
 * Mask builders used by the AI Harmonize pipeline.
 *
 *  - `layerUnionAlpha`  — union of every non-base layer's alpha, as a
 *                         binary (0/255) mask. Used as the substrate
 *                         for both seam and body masks.
 *  - `seamMask`         — feathered band along the alpha edges of all
 *                         non-base layers. White = "blend here",
 *                         black = "leave alone". Returned as base64
 *                         PNG (so it can be POST'd to the diffusion
 *                         endpoint as JSON).
 *  - `layerBodyMask`    — feathered FULL shape of every non-base layer.
 *                         White = "AI may redraw this pixel using the
 *                         existing pixels as a starting point";
 *                         black = "preserve exactly". Returned as base64.
 *
 * Each helper takes the visible layer list + the doc dimensions; no
 * module state.
 *
 * @typedef {{ visible: boolean, id: string, canvas: HTMLCanvasElement, offset: {x: number, y: number} }} HarmLayer
 */

/**
 * Build a binary alpha mask = the UNION of every non-base visible
 * layer's pixels. Returns null when fewer than 2 visible layers exist
 * or when the non-base layers are entirely transparent.
 *
 * @param {number} w / h          Canvas dimensions in pixels.
 * @param {HarmLayer[]} layers    All layers in stack order; the
 *                                first VISIBLE layer is treated as
 *                                the base / background.
 * @returns {HTMLCanvasElement|null}
 */
export function layerUnionAlpha(w, h, layers) {
  if (!Array.isArray(layers)) return null;
  const visible = layers.filter(l => l.visible);
  if (visible.length < 2) return null;
  const bgId = visible[0].id;
  const alphaCanvas = document.createElement('canvas');
  alphaCanvas.width = w; alphaCanvas.height = h;
  const actx = alphaCanvas.getContext('2d');
  let hasFg = false;
  for (const layer of visible) {
    if (layer.id === bgId) continue;
    const off = layer.offset || { x: 0, y: 0 };
    actx.drawImage(layer.canvas, off.x, off.y);
    hasFg = true;
  }
  if (!hasFg) return null;
  const src = actx.getImageData(0, 0, w, h);
  const bin = document.createElement('canvas');
  bin.width = w; bin.height = h;
  const bctx = bin.getContext('2d');
  const binImg = bctx.createImageData(w, h);
  let any = false;
  for (let i = 0; i < src.data.length; i += 4) {
    const v = src.data[i + 3] > 0 ? 255 : 0;
    if (v) any = true;
    binImg.data[i] = binImg.data[i + 1] = binImg.data[i + 2] = v;
    binImg.data[i + 3] = 255;
  }
  if (!any) return null;
  bctx.putImageData(binImg, 0, 0);
  return bin;
}


/**
 * Build a feathered seam mask along the alpha edges of all non-base
 * visible layers. Returns base64-encoded PNG (no `data:` prefix), or
 * null if there's nothing to harmonize.
 */
export function seamMask(w, h, layers, featherPx = 12) {
  const bin = layerUnionAlpha(w, h, layers);
  if (!bin) return null;
  const blur = document.createElement('canvas');
  blur.width = w; blur.height = h;
  const blctx = blur.getContext('2d');
  blctx.filter = `blur(${featherPx}px)`;
  blctx.drawImage(bin, 0, 0);
  blctx.filter = 'none';
  const blurred = blctx.getImageData(0, 0, w, h);
  const mask = blctx.createImageData(w, h);
  // Triangular weight peaked at mid-grey — picks out the alpha-edge band.
  for (let i = 0; i < blurred.data.length; i += 4) {
    const v = blurred.data[i];
    const dist = Math.abs(v - 128);
    const wt = Math.max(0, 255 - dist * 2);
    mask.data[i] = mask.data[i + 1] = mask.data[i + 2] = wt;
    mask.data[i + 3] = 255;
  }
  blctx.putImageData(mask, 0, 0);
  const soft = document.createElement('canvas');
  soft.width = w; soft.height = h;
  const sctx = soft.getContext('2d');
  sctx.filter = `blur(${Math.max(2, Math.floor(featherPx / 4))}px)`;
  sctx.drawImage(blur, 0, 0);
  sctx.filter = 'none';
  return soft.toDataURL('image/png').split(',')[1];
}


/**
 * Build a feathered FULL-shape mask of every non-base visible layer.
 * Returns base64-encoded PNG, or null if there are no non-base layers.
 */
export function layerBodyMask(w, h, layers, featherPx = 12) {
  const bin = layerUnionAlpha(w, h, layers);
  if (!bin) return null;
  const soft = document.createElement('canvas');
  soft.width = w; soft.height = h;
  const sctx = soft.getContext('2d');
  sctx.filter = `blur(${featherPx}px)`;
  sctx.drawImage(bin, 0, 0);
  sctx.filter = 'none';
  return soft.toDataURL('image/png').split(',')[1];
}
