export const NORMALIZED_STEP_IMAGE_WIDTH = 1600;
export const NORMALIZED_STEP_IMAGE_HEIGHT = 900;
export const NORMALIZED_STEP_IMAGE_TYPE = "image/webp";
export const NORMALIZED_STEP_IMAGE_QUALITY = 0.85;

export type CoverCrop = { sx: number; sy: number; sw: number; sh: number };

export function calculateCenteredCoverCrop(sourceWidth: number, sourceHeight: number): CoverCrop {
  if (sourceWidth <= 0 || sourceHeight <= 0) throw new Error("Dimensions d’image invalides.");
  const targetRatio = NORMALIZED_STEP_IMAGE_WIDTH / NORMALIZED_STEP_IMAGE_HEIGHT;
  const sourceRatio = sourceWidth / sourceHeight;
  if (sourceRatio > targetRatio) {
    const sw = sourceHeight * targetRatio;
    return { sx: (sourceWidth - sw) / 2, sy: 0, sw, sh: sourceHeight };
  }
  const sh = sourceWidth / targetRatio;
  return { sx: 0, sy: (sourceHeight - sh) / 2, sw: sourceWidth, sh };
}

function canvasBlob(canvas: HTMLCanvasElement) {
  return new Promise<Blob>((resolve, reject) => canvas.toBlob(
    (blob) => blob ? resolve(blob) : reject(new Error("La conversion de l’image a échoué.")),
    NORMALIZED_STEP_IMAGE_TYPE,
    NORMALIZED_STEP_IMAGE_QUALITY,
  ));
}

function transparentContentBounds(bitmap: ImageBitmap): CoverCrop {
  const scale = Math.min(1, 512 / Math.max(bitmap.width, bitmap.height));
  const width = Math.max(1, Math.round(bitmap.width * scale));
  const height = Math.max(1, Math.round(bitmap.height * scale));
  const canvas = document.createElement("canvas");
  canvas.width = width; canvas.height = height;
  const context = canvas.getContext("2d", { willReadFrequently: true });
  if (!context) return { sx: 0, sy: 0, sw: bitmap.width, sh: bitmap.height };
  context.clearRect(0, 0, width, height);
  context.drawImage(bitmap, 0, 0, width, height);
  const pixels = context.getImageData(0, 0, width, height).data;
  let left = width; let top = height; let right = -1; let bottom = -1;
  for (let y = 0; y < height; y += 1) for (let x = 0; x < width; x += 1) {
    if (pixels[(y * width + x) * 4 + 3] > 8) { left = Math.min(left, x); top = Math.min(top, y); right = Math.max(right, x); bottom = Math.max(bottom, y); }
  }
  if (right < left || bottom < top) return { sx: 0, sy: 0, sw: bitmap.width, sh: bitmap.height };
  return { sx: left / scale, sy: top / scale, sw: (right - left + 1) / scale, sh: (bottom - top + 1) / scale };
}

export async function normalizeStepImage(file: File): Promise<File> {
  const bitmap = await createImageBitmap(file);
  try {
    const content = transparentContentBounds(bitmap);
    const centered = calculateCenteredCoverCrop(content.sw, content.sh);
    const crop = { ...centered, sx: content.sx + centered.sx, sy: content.sy + centered.sy };
    const canvas = document.createElement("canvas");
    canvas.width = NORMALIZED_STEP_IMAGE_WIDTH;
    canvas.height = NORMALIZED_STEP_IMAGE_HEIGHT;
    const context = canvas.getContext("2d", { alpha: false });
    if (!context) throw new Error("Votre navigateur ne permet pas de préparer cette image.");
    context.drawImage(bitmap, crop.sx, crop.sy, crop.sw, crop.sh, 0, 0, canvas.width, canvas.height);
    const blob = await canvasBlob(canvas);
    const baseName = file.name.replace(/\.[^.]+$/, "") || "photo-etape";
    return new File([blob], `${baseName}.webp`, { type: NORMALIZED_STEP_IMAGE_TYPE, lastModified: Date.now() });
  } finally {
    bitmap.close();
  }
}
