import { describe, expect, test } from 'vitest';
import { decodePositionId, toBigIntId } from '../ids.js';
import { uint256ToBytesLittleEndian } from '../subgraph.js';

describe('decodePositionId', () => {
  test('works across bigint, hex string, and Uint8Array representations', () => {
    const id = 12345n;
    const hex = `0x${id.toString(16)}`;
    const bytes = uint256ToBytesLittleEndian(id);

    expect(decodePositionId(id)).toBe(id);
    expect(decodePositionId(hex)).toBe(id);
    expect(decodePositionId(bytes)).toBe(id);
  });
});

describe('toBigIntId', () => {
  test('returns bigint unchanged', () => {
    expect(toBigIntId(42n)).toBe(42n);
    expect(toBigIntId(0n)).toBe(0n);
  });

  test('converts number to bigint', () => {
    expect(toBigIntId(42)).toBe(42n);
    expect(toBigIntId(0)).toBe(0n);
    expect(toBigIntId(1000)).toBe(1000n);
  });

  test('converts hex string with 0x prefix to bigint', () => {
    expect(toBigIntId('0x3039')).toBe(12345n);
    expect(toBigIntId('0x0')).toBe(0n);
    expect(toBigIntId('0x1')).toBe(1n);
  });

  test('converts string without 0x prefix (prepends 0x, treats as hex)', () => {
    expect(toBigIntId('3039')).toBe(12345n);
    expect(toBigIntId('0')).toBe(0n);
    expect(toBigIntId('ff')).toBe(255n);
  });

  test('converts Uint8Array via little endian decoding', () => {
    const bytes = uint256ToBytesLittleEndian(12345n);
    expect(toBigIntId(bytes)).toBe(12345n);

    const zeroBytes = uint256ToBytesLittleEndian(0n);
    expect(toBigIntId(zeroBytes)).toBe(0n);
  });

  test('throws for unsupported type', () => {
    expect(() => toBigIntId({} as unknown as bigint)).toThrow('Unsupported position id type');
  });
});
