'use strict';

const { test } = require('node:test');
const assert = require('node:assert');
const { toCents, fromCents, roundMoney, sumMoney, mulMoney, formatUSD, formatCentsUSD } = require('../utils/money.mts');

test('toCents — unchanged for integer / ≤2-decimal / formatted inputs', () => {
  assert.strictEqual(toCents(0), 0);
  assert.strictEqual(toCents(85), 8500);
  assert.strictEqual(toCents(19.99), 1999);
  assert.strictEqual(toCents(100.001), 10000); // 3rd decimal <5 rounds down (10000.1)
  assert.strictEqual(toCents('$1,234.56'), 123456);
  assert.strictEqual(toCents('9,999,999.99'), 999999999);
  assert.strictEqual(toCents(0.1), 10);
  assert.strictEqual(toCents(0.1 + 0.2), 30); // 0.30000000000000004 → 30, not 30.000…
});

test('toCents — QA-B7-01: fractional half-cents round half away from zero (was buggy)', () => {
  assert.strictEqual(toCents(1.005), 101); // was 100 with Math.round(n*100)
  assert.strictEqual(toCents(2.675), 268); // was 267
  assert.strictEqual(toCents(0.005), 1);
  assert.strictEqual(toCents('1.005'), 101);
  assert.strictEqual(toCents(1.004), 100);
});

test('toCents — negatives and nullish/invalid', () => {
  assert.strictEqual(toCents(-50), -5000);
  assert.strictEqual(toCents('-12.34'), -1234);
  assert.strictEqual(toCents(null), null);
  assert.strictEqual(toCents(undefined), null);
  assert.strictEqual(toCents(''), null);
  assert.ok(Number.isNaN(toCents('abc')));
});

test('toCents — round-trips through fromCents for money values', () => {
  for (const v of [0, 85, 19.99, 1234.56, 0.01]) {
    assert.strictEqual(fromCents(toCents(v)), v);
  }
});

test('fromCents', () => {
  assert.strictEqual(fromCents(8500), 85);
  assert.strictEqual(fromCents(null), null);
  assert.strictEqual(fromCents(undefined), null);
});

test('sumMoney — cent-exact, no float drift', () => {
  assert.strictEqual(sumMoney([0.1, 0.2]), 0.3);
  assert.strictEqual(sumMoney([{ a: 1.11 }, { a: 2.22 }], (r) => r.a), 3.33);
  assert.strictEqual(sumMoney([]), 0);
});

test('mulMoney — rounds to the cent', () => {
  assert.strictEqual(mulMoney(100, 0.1), 10);
  assert.strictEqual(mulMoney(19.99, 2), 39.98);
  assert.strictEqual(mulMoney('bad', 2), 0);
});

test('roundMoney', () => {
  assert.strictEqual(roundMoney(1.005), 1.01); // benefits from the toCents fix
  assert.strictEqual(roundMoney(19.994), 19.99);
  assert.strictEqual(roundMoney('abc'), 0);
});

test('formatUSD / formatCentsUSD — negative sign before the symbol (QA-B6-01)', () => {
  assert.strictEqual(formatUSD(50), '$50.00');
  assert.strictEqual(formatUSD(-50), '-$50.00');
  assert.strictEqual(formatUSD(-1234.5), '-$1,234.50');
  assert.strictEqual(formatUSD(0), '$0.00');
  assert.strictEqual(formatUSD(null), '$0.00');
  assert.strictEqual(formatCentsUSD(123456), '$1,234.56');
  assert.strictEqual(formatCentsUSD(-5000), '-$50.00');
});
