import type { UploadFile } from './common'; import { audioExt } from './files'; type SummaryFile = Pick; function range(values: (number | null)[], divisor: number, decimals: number, unit: string): string | null { const known = values.filter((value): value is number => value !== null && Number.isFinite(value) && value > 0); if (!known.length) return null; const format = (value: number) => String(Number((value / divisor).toFixed(decimals))); const min = format(Math.min(...known)); const max = format(Math.max(...known)); return `${min === max ? min : `${min}–${max}`} ${unit}`; } /** Only measured positive values contribute to quality ranges; absent metadata is not zero. */ export function batchSummary(files: SummaryFile[]) { const counts = new Map(); for (const file of files) { const format = (file.format?.trim() || audioExt(file.original_name)).toUpperCase(); counts.set(format, (counts.get(format) ?? 0) + 1); } return { formats: [...counts].sort(([a, ac], [b, bc]) => bc - ac || a.localeCompare(b)), quality: [ range(files.map((file) => file.bitrate), 1000, 0, 'kbps'), range(files.map((file) => file.sample_rate), 1000, 3, 'kHz'), range(files.map((file) => file.bit_depth), 1, 0, 'bit'), ].filter(Boolean).join(' · '), }; }