/** Exact fixed-point helpers. Values are decimal strings, never JS numbers. */
const DECIMAL_RE = /^[+-]?\d+(\.\d+)?$/;
export function parseDecimal(value: string): { coefficient: bigint; scale: number } {
  const normalized = value.trim().replace(/,/g, '');
  if (!DECIMAL_RE.test(normalized)) throw new Error(`Invalid decimal: ${value}`);
  const sign = normalized.startsWith('-') ? -1n : 1n;
  const plain = normalized.replace(/^[+-]/, '');
  const [whole, fraction = ''] = plain.split('.');
  return { coefficient: sign * BigInt(`${whole}${fraction}`), scale: fraction.length };
}
export function formatDecimal(coefficient: bigint, scale: number): string {
  const sign = coefficient < 0n ? '-' : ''; const digits = (coefficient < 0n ? -coefficient : coefficient).toString().padStart(scale + 1, '0');
  if (scale === 0) return `${sign}${digits}`;
  const output = `${sign}${digits.slice(0, -scale)}.${digits.slice(-scale)}`;
  return output.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '');
}
export function addDecimals(values: string[]): string {
  const parts = values.map(parseDecimal); const scale = Math.max(0, ...parts.map(p => p.scale));
  const sum = parts.reduce((total, p) => total + p.coefficient * 10n ** BigInt(scale - p.scale), 0n);
  return formatDecimal(sum, scale);
}
export function compareDecimals(a: string, b: string): number {
  const [x, y] = [parseDecimal(a), parseDecimal(b)]; const scale = Math.max(x.scale, y.scale);
  const left = x.coefficient * 10n ** BigInt(scale - x.scale); const right = y.coefficient * 10n ** BigInt(scale - y.scale);
  return left === right ? 0 : left > right ? 1 : -1;
}
/** 取反（零值特殊处理，避免产生 "-0"）。 */
export function negateDecimal(value: string): string {
  if (value === '0' || value === '-0') return '0';
  return value.startsWith('-') ? value.slice(1) : `-${value}`;
}
export function subtractDecimals(a: string, b: string): string { return addDecimals([a, negateDecimal(b)]); }
export function multiplyDecimals(a: string, b: string): string {
  const x = parseDecimal(a); const y = parseDecimal(b);
  return formatDecimal(x.coefficient * y.coefficient, x.scale + y.scale);
}
/**
 * 除法（a ÷ b），结果保留 maxScale 位小数（默认 6，适用于汇率）。
 * 注意：使用 BigInt 整除（向零截断），负数结果向零方向舍入。
 * 如需银行家舍入或向上/向下取整，调用方应自行处理。
 */
export function divideDecimals(a: string, b: string, maxScale = 6): string {
  const x = parseDecimal(a); const y = parseDecimal(b);
  if (y.coefficient === 0n) throw new Error('除数不能为零');
  const precision = 10n ** BigInt(maxScale);
  const num = x.coefficient * precision * 10n ** BigInt(y.scale);
  const den = y.coefficient * 10n ** BigInt(x.scale);
  return formatDecimal(num / den, maxScale);
}


/** Date → "YYYY-MM-DD"（本地时区）。 */
export function toDateString(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}
