/**
 * Pure layout math shared by ContainedVideo / RotatedImage contain-mode.
 * Kept free of DOM so unit tests can lock overlay alignment for video scenes.
 */

export type MediaRotationDeg = 0 | 90 | 180 | 270;

export type ContainMediaRect = { x: number; y: number; w: number; h: number };

export type ContainMediaLayout = {
  /** Bounding box of the visible media after rotation (overlay coordinate space). */
  contentRect: ContainMediaRect;
  /** Unrotated element size; apply CSS rotate(rotationDeg) on the media node. */
  elementW: number;
  elementH: number;
};

export function containMediaLayout(args: {
  hostW: number;
  hostH: number;
  mediaW: number;
  mediaH: number;
  scale: number;
  ox: number;
  oy: number;
  rotationDeg?: MediaRotationDeg;
  mode?: 'contain' | 'cover';
}): ContainMediaLayout | null {
  const {
    hostW,
    hostH,
    mediaW,
    mediaH,
    scale,
    ox,
    oy,
    rotationDeg = 0,
    mode = 'contain',
  } = args;
  if (hostW <= 1 || hostH <= 1 || mediaW <= 0 || mediaH <= 0) return null;
  const rotated = rotationDeg === 90 || rotationDeg === 270;
  const layoutW = rotated ? mediaH : mediaW;
  const layoutH = rotated ? mediaW : mediaH;
  const sx = hostW / layoutW;
  const sy = hostH / layoutH;
  const fit = mode === 'cover' ? Math.max(sx, sy) : Math.min(sx, sy);
  const s = fit * Math.max(1, scale);
  const w = layoutW * s;
  const h = layoutH * s;
  return {
    contentRect: {
      x: hostW / 2 - ox * w,
      y: hostH / 2 - oy * h,
      w,
      h,
    },
    elementW: mediaW * s,
    elementH: mediaH * s,
  };
}

export function containMediaRect(args: {
  hostW: number;
  hostH: number;
  mediaW: number;
  mediaH: number;
  scale: number;
  ox: number;
  oy: number;
  rotationDeg?: MediaRotationDeg;
  mode?: 'contain' | 'cover';
}): ContainMediaRect | null {
  return containMediaLayout(args)?.contentRect ?? null;
}
