import { D, sum, weekKey, monthKey, addDays, daysBetween, serialize, chunk } from '@/common/util';

describe('common/util', () => {
  it('decimal helpers never lose precision', () => {
    expect(sum(['0.1', '0.2']).toString()).toBe('0.3');
    expect(D('12.0000').toFixed(4)).toBe('12.0000');
    expect(D(null).isZero()).toBe(true);
  });

  it('weekKey groups by ISO-like week starting Monday by default', () => {
    const w = weekKey('2026-10-07'); // Wednesday
    expect(w.start).toBe('2026-10-05');
    expect(w.end).toBe('2026-10-11');
    expect(w.key).toMatch(/^2026-W\d{2}$/);
    const sunday = weekKey('2026-10-07', 0);
    expect(sunday.start).toBe('2026-10-04');
  });

  it('date helpers', () => {
    expect(addDays('2026-01-31', 1)).toBe('2026-02-01');
    expect(daysBetween('2026-01-01', '2026-01-31')).toBe(30);
    expect(monthKey('2026-10-07')).toBe('2026-10');
  });

  it('serialize turns decimals into plain strings and leaves dates for the JSON layer', () => {
    const out = serialize({ qty: D('1.5'), nested: [{ money: D(2) }], when: new Date('2026-01-01T00:00:00Z'), text: 'x' }) as unknown as { qty: string; nested: { money: string }[]; when: unknown };
    expect(out.qty).toBe('1.5');
    expect(out.nested[0].money).toBe('2');
    expect(new Date(out.when as string).toISOString()).toBe('2026-01-01T00:00:00.000Z');
  });

  it('chunk splits arrays', () => {
    expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]);
  });
});
