// Shared byte-size formatter for the Downloads surface.
//
// One formatter, used everywhere disk usage is shown (cards, detail pages, the
// device total, and the remove-reclaim prompt) so units are consistent. We use
// DECIMAL units (1 GB = 1000 MB), matching how phone storage screens and file
// browsers present sizes, and show 2–3 significant figures.
//
// TRACES: UR-056 | DR-085

const UNITS = ["B", "KB", "MB", "GB", "TB", "PB"] as const;

/**
 * Format a byte count as a human-readable size string (decimal units).
 *
 * Examples: 0 → "0 B", 340_000_000 → "340 MB", 1_200_000_000 → "1.2 GB".
 *
 * - Bytes render as whole numbers (no "0.5 B").
 * - KB and above show enough decimals for 2–3 significant figures: values
 *   ≥ 100 render with no decimals, ≥ 10 with one, otherwise two.
 * - Negative / non-finite inputs are treated as 0 (sizes are never negative).
 */
export function formatBytes(bytes: number): string {
  if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";

  let value = bytes;
  let unitIndex = 0;
  while (value >= 1000 && unitIndex < UNITS.length - 1) {
    value /= 1000;
    unitIndex += 1;
  }

  // Bytes are always whole; larger units get 2–3 significant figures.
  let formatted: string;
  if (unitIndex === 0) {
    formatted = Math.round(value).toString();
  } else if (value >= 100) {
    formatted = Math.round(value).toString();
  } else if (value >= 10) {
    formatted = value.toFixed(1);
  } else {
    formatted = value.toFixed(2);
  }

  // Trim trailing zeros ("1.20" → "1.2", "1.00" → "1") for a cleaner label.
  if (formatted.includes(".")) {
    formatted = formatted.replace(/\.?0+$/, "");
  }

  return `${formatted} ${UNITS[unitIndex]}`;
}
