/**
 * Unit tests for src/utils/crypto.ts
 */

import { generateClientSecret, hashSecret, verifySecret } from '../../../src/utils/crypto';

describe('crypto utils', () => {
  describe('generateClientSecret()', () => {
    it('should return a string starting with sk_live_', () => {
      const secret = generateClientSecret();
      expect(secret).toMatch(/^sk_live_/);
    });

    it('should return 64 hex chars after the prefix', () => {
      const secret = generateClientSecret();
      const hex = secret.slice('sk_live_'.length);
      expect(hex).toHaveLength(64);
      expect(hex).toMatch(/^[0-9a-f]{64}$/);
    });

    it('should generate unique secrets on each call', () => {
      const secret1 = generateClientSecret();
      const secret2 = generateClientSecret();
      expect(secret1).not.toBe(secret2);
    });

    it('should have total length of 72 characters (8 + 64)', () => {
      const secret = generateClientSecret();
      expect(secret).toHaveLength(72);
    });
  });

  describe('hashSecret() and verifySecret()', () => {
    it('should hash a secret and verify it correctly', async () => {
      const plain = generateClientSecret();
      const hash = await hashSecret(plain);
      const isValid = await verifySecret(plain, hash);
      expect(isValid).toBe(true);
    });

    it('should return false for a wrong secret', async () => {
      const plain = generateClientSecret();
      const hash = await hashSecret(plain);
      const isValid = await verifySecret('wrong_secret', hash);
      expect(isValid).toBe(false);
    });

    it('should produce different hashes for the same input (salt randomness)', async () => {
      const plain = generateClientSecret();
      const hash1 = await hashSecret(plain);
      const hash2 = await hashSecret(plain);
      expect(hash1).not.toBe(hash2);
    });

    it('should produce a bcrypt hash string', async () => {
      const plain = generateClientSecret();
      const hash = await hashSecret(plain);
      // bcrypt hashes start with $2a$ or $2b$
      expect(hash).toMatch(/^\$2[ab]\$/);
    });
  });
});
