export type UnitScale = 'raw' | 'T' | 'M' | 'B';
export type UnitOption = 'auto' | 'T' | 'M' | 'B';

export const UNIT_OPTIONS: { value: UnitOption; label: string }[] = [
  { value: 'auto', label: 'Auto' },
  { value: 'T', label: 'Thousands' },
  { value: 'M', label: 'Millions' },
  { value: 'B', label: 'Billions' },
];

export const UNIT_DIVISOR: Record<UnitScale, number> = {
  raw: 1,
  T: 1e3,
  M: 1e6,
  B: 1e9,
};

const moneyFormatter = new Intl.NumberFormat('en-US', {
  maximumFractionDigits: 2,
});

export function computeAutoUnit(
  values: (number | null | undefined)[],
): UnitScale {
  const maxAbs = Math.max(
    0,
    ...values
      .filter((v): v is number => v != null && !Number.isNaN(v))
      .map(Math.abs),
  );
  if (maxAbs >= 5e8) return 'B';
  if (maxAbs >= 5e5) return 'M';
  if (maxAbs >= 5e2) return 'T';
  return 'raw';
}

export function formatScaled(
  value: number | null | undefined,
  unit: UnitScale,
): string {
  if (value === null || value === undefined || Number.isNaN(value)) return '\u2014';
  return moneyFormatter.format(value / UNIT_DIVISOR[unit]);
}

const WARNING_NUMBER_RE = /\d+\.\d{2}/g;

export function scaleWarningNumbers(warning: string, unit: UnitScale): string {
  if (unit === 'raw') return warning;
  const divisor = UNIT_DIVISOR[unit];
  return warning.replace(WARNING_NUMBER_RE, (match) => {
    const value = parseFloat(match);
    if (Number.isNaN(value)) return match;
    return moneyFormatter.format(value / divisor);
  });
}

export function unitLabel(unit: UnitScale): string {
  switch (unit) {
    case 'B': return 'Billions';
    case 'M': return 'Millions';
    case 'T': return 'Thousands';
    case 'raw': return 'Units';
  }
}
