import { describe, expect, test } from 'vitest';
import { weiToNumber, formatWei, compactNumber, commaNumber } from '../format.js';

describe('weiToNumber', () => {
  test('returns 0 for zero bigint', () => {
    expect(weiToNumber(0n)).toBe(0);
  });

  test('returns 0 for empty string', () => {
    expect(weiToNumber('')).toBe(0);
  });

  test('converts 1 ether bigint to 1', () => {
    expect(weiToNumber(1_000_000_000_000_000_000n)).toBe(1);
  });

  test('converts string wei to number', () => {
    expect(weiToNumber('1000000000000000000')).toBe(1);
  });

  test('handles small values correctly', () => {
    expect(weiToNumber(1n)).toBeCloseTo(1e-18);
  });

  test('handles large values', () => {
    expect(weiToNumber(1_000_000_000_000_000_000_000n)).toBe(1000);
  });

  test('respects custom decimals', () => {
    expect(weiToNumber(1_000_000n, 6)).toBe(1);
  });

  test('handles string with custom decimals', () => {
    expect(weiToNumber('1000000', 6)).toBe(1);
  });

  test('handles null/undefined via nullish coalescing fallback', () => {
    expect(weiToNumber(null as unknown as bigint)).toBe(0);
    expect(weiToNumber(undefined as unknown as bigint)).toBe(0);
  });
});

describe('formatWei', () => {
  test('returns "0" for zero bigint', () => {
    expect(formatWei(0n)).toBe('0');
  });

  test('returns "0" for zero string', () => {
    expect(formatWei('0')).toBe('0');
  });

  test('formats 1 ether with default 5 digits', () => {
    expect(formatWei(1_000_000_000_000_000_000n)).toBe('1.00000');
  });

  test('formats with custom digits', () => {
    expect(formatWei(1_000_000_000_000_000_000n, 18, 2)).toBe('1.00');
  });

  test('formats small value', () => {
    const result = formatWei(1_230_000_000_000_000n, 18, 5);
    expect(result).toBe('0.00123');
  });

  test('formats string input', () => {
    expect(formatWei('2000000000000000000', 18, 4)).toBe('2.0000');
  });

  test('formats large values', () => {
    const wei = 1_000_000n * 10n ** 18n;
    expect(formatWei(wei, 18, 2)).toBe('1000000.00');
  });
});

describe('compactNumber', () => {
  test('formats thousands', () => {
    expect(compactNumber(1234)).toBe('1.23K');
  });

  test('formats millions', () => {
    expect(compactNumber(4_560_000)).toBe('4.56M');
  });

  test('formats zero', () => {
    expect(compactNumber(0)).toBe('0');
  });

  test('formats small number without suffix', () => {
    expect(compactNumber(123)).toBe('123');
  });

  test('formats billions', () => {
    expect(compactNumber(1_000_000_000)).toBe('1B');
  });
});

describe('commaNumber', () => {
  test('returns "0" for zero', () => {
    expect(commaNumber(0)).toBe('0');
  });

  test('returns "0" for NaN', () => {
    expect(commaNumber(NaN)).toBe('0');
  });

  test('returns "0" for Infinity', () => {
    expect(commaNumber(Infinity)).toBe('0');
  });

  test('formats thousands with commas', () => {
    expect(commaNumber(1234)).toBe('1,234');
  });

  test('formats millions with commas', () => {
    expect(commaNumber(1_234_567)).toBe('1,234,567');
  });

  test('formats small number without commas', () => {
    expect(commaNumber(99)).toBe('99');
  });

  test('formats negative number', () => {
    expect(commaNumber(-1234)).toBe('-1,234');
  });
});
