/**
 * Pure, DOM-free helpers for the image-sequence quad-viewer. Fully unit-testable —
 * no React, no `<img>`, no VTK. The `ImageSequenceViewer` component composes these.
 *
 * The sequence viewer mirrors the video viewer but is driven by a frame index over
 * an array of 2D PNG frames (original / depth / segmentation) instead of a
 * `<video>` currentTime. These helpers cover clamping the frame index, natural
 * (numeric) sorting of frame files, and the Vietnamese pane labels / counters.
 */
import type { QuadIndex } from './types';

/**
 * Clamp a frame index to the valid range [0, max(0, count - 1)].
 * Guards NaN / negative inputs and an empty (count <= 0) sequence → 0.
 */
export function clampFrame(i: number, count: number): number {
  if (!Number.isFinite(count) || count <= 0) return 0;
  const max = count - 1;
  if (!Number.isFinite(i) || i < 0) return 0;
  return i > max ? max : Math.floor(i);
}

/** Vietnamese labels for the four image quad panes. Diacritics preserved. */
export const IMAGE_QUAD_LABELS: Record<QuadIndex, string> = {
  0: 'Ảnh gốc',
  1: 'Bản đồ độ sâu',
  2: 'Phủ phân vùng',
  3: 'Tái tạo 3D',
};

/**
 * Sort items by a string key using a natural (numeric-aware) comparison so frame
 * names order as humans expect: `frame2` < `frame10`. Returns a new array; the
 * input is left untouched.
 */
export function naturalSortBy<T>(items: T[], key: (t: T) => string): T[] {
  return [...items].sort((a, b) =>
    key(a).localeCompare(key(b), undefined, { numeric: true, sensitivity: 'base' }),
  );
}

/**
 * Sort frame files by `file.name` with a natural (numeric-aware) comparison, so
 * `['f10.png','f2.png','f1.png']` → `['f1.png','f2.png','f10.png']`. Returns a new
 * array; the input array is not mutated.
 */
export function naturalSortFiles(files: File[]): File[] {
  return naturalSortBy(files, (f) => f.name);
}

/**
 * Human-readable 1-based frame counter, e.g. `khung 5/10`. An empty sequence
 * (count 0) → `khung 0/0`. Diacritics preserved.
 */
export function frameLabel(i: number, count: number): string {
  return count ? `khung ${clampFrame(i, count) + 1}/${count}` : 'khung 0/0';
}
