/** Shared size policy for server vision JPEGs and client upload prepare. */

export const AI_IMAGE_LONG_EDGE_PX = 1536;
/** Tall thermal slips stay readable on the short axis. */
export const AI_IMAGE_MIN_WIDTH_PX = 1100;
/** Safety cap so a 20:1 strip does not become a 15k-px JPEG. */
export const AI_IMAGE_MAX_LONG_EDGE_PX = 4096;
const DEFAULT_MAX_UPSCALE = 1.5;
const TALL_ASPECT = 1.35;

export interface ReceiptResizeTargets {
  defaultLongEdge?: number;
  minWidth?: number;
  maxLongEdge?: number;
  /** Vector PDFs can be rasterized above their native point size. */
  allowUpscale?: boolean;
  maxUpscale?: number;
}

export interface ReceiptResize {
  width: number;
  height: number;
}

/**
 * Size the vision JPEG. Landscape / squarish photos still fit in
 * {@link AI_IMAGE_LONG_EDGE_PX}. Tall thermal photos keep a usable width
 * even if that makes the long edge exceed 1536.
 */
export function computeReceiptResize(
  srcWidth: number,
  srcHeight: number,
  targets: ReceiptResizeTargets = {}
): ReceiptResize {
  const srcW = Math.max(1, Math.round(srcWidth));
  const srcH = Math.max(1, Math.round(srcHeight));
  const defaultLong = targets.defaultLongEdge ?? AI_IMAGE_LONG_EDGE_PX;
  const minWidth = targets.minWidth ?? AI_IMAGE_MIN_WIDTH_PX;
  const maxLong = targets.maxLongEdge ?? AI_IMAGE_MAX_LONG_EDGE_PX;
  const maxUpscale = targets.maxUpscale ?? (targets.allowUpscale ? 4 : DEFAULT_MAX_UPSCALE);
  const long = Math.max(srcW, srcH);

  let scale = targets.allowUpscale
    ? Math.min(maxLong / long, Math.max(1, defaultLong / long))
    : Math.min(1, defaultLong / long);

  let width = srcW * scale;
  let height = srcH * scale;

  const isTall = srcH / srcW >= TALL_ASPECT;
  if (isTall && width < minWidth) {
    const needed = minWidth / srcW;
    const heightCap = maxLong / srcH;
    const applied = Math.min(needed, maxUpscale, heightCap);
    if (applied > scale) {
      scale = applied;
      width = srcW * scale;
      height = srcH * scale;
    }
  }

  const newLong = Math.max(width, height);
  if (newLong > maxLong) {
    const cap = maxLong / newLong;
    width *= cap;
    height *= cap;
  }

  return {
    width: Math.max(1, Math.round(width)),
    height: Math.max(1, Math.round(height)),
  };
}
