import { beforeEach, describe, expect, it, vi } from 'vitest';
import nacl from 'tweetnacl';
import bs58 from 'bs58';

import { signRequest } from '../packages/connectors/pacifica/src/signing';

const seed = new Uint8Array(32).fill(7);
const { secretKey, publicKey } = nacl.sign.keyPair.fromSeed(seed);
const secretBase64 = Buffer.from(secretKey).toString('base64');

describe('signRequest', () => {
  beforeEach(() => {
    vi.restoreAllMocks();
  });

  it('signs payloads according to Pacifica spec', () => {
    const body = { foo: 'bar', amount: 1 };
    vi.spyOn(Date, 'now').mockReturnValue(1_700_000_000_000);

    const apiKey = bs58.encode(publicKey);
    const { headers, body: serialized } = signRequest(
      {
        apiKey,
        secret: secretBase64
      },
      'POST',
      '/orders',
      body
    );

    expect(headers['X-Pacific-Key']).toBe(apiKey);
    expect(headers['X-Pacific-Signature']).toBeTruthy();
    expect(headers['X-Pacific-Timestamp']).toBe('1700000000000');
    expect(serialized).toBe(JSON.stringify(body));

    const baseString = `${headers['X-Pacific-Timestamp']}:POST:/orders:${serialized}`;
    const signatureBytes = Buffer.from(headers['X-Pacific-Signature'], 'base64');
    const valid = nacl.sign.detached.verify(
      new TextEncoder().encode(baseString),
      signatureBytes,
      publicKey
    );
    expect(valid).toBe(true);
  });

  it('omits signature headers when api credentials are missing', () => {
    const { headers, body } = signRequest({}, 'GET', '/products/BTC', undefined);
    expect(headers).toEqual({});
    expect(body).toBe('');
  });
});
