const ESC = "\x1B";
const GS = "\x1D";

/** GS v 0 raster bit image (widely supported on Epson thermal printers). */
function rasterToEscPos(raster, widthPx, heightPx, align = "center") {
  const bytesPerRow = Math.ceil(widthPx / 8);
  const xL = bytesPerRow % 256;
  const xH = Math.floor(bytesPerRow / 256);
  const yL = heightPx % 256;
  const yH = Math.floor(heightPx / 256);
  let out = "";
  if (align === "right") out += ESC + "a" + "\x02";
  else if (align === "left") out += ESC + "a" + "\x00";
  else out += ESC + "a" + "\x01";
  out += GS + "v0" + "\x00";
  out += String.fromCharCode(xL, xH, yL, yH);
  out += raster;
  out += "\n";
  return out;
}

function imageDataToRaster(imageData, width, height) {
  const bytesPerRow = Math.ceil(width / 8);
  const raster = Buffer.alloc(bytesPerRow * height, 0);

  for (let y = 0; y < height; y += 1) {
    for (let x = 0; x < width; x += 1) {
      const idx = (y * width + x) * 4;
      const r = imageData[idx];
      const g = imageData[idx + 1];
      const b = imageData[idx + 2];
      const a = imageData[idx + 3];
      const lum = 0.299 * r + 0.587 * g + 0.114 * b;
      const isBlack = a > 64 && lum < 210;
      if (isBlack) {
        const byteIndex = y * bytesPerRow + Math.floor(x / 8);
        raster[byteIndex] |= 0x80 >> x % 8;
      }
    }
  }

  return { raster: raster.toString("binary"), widthPx: width, heightPx: height };
}

module.exports = { rasterToEscPos, imageDataToRaster };
