import { describe, expect, it } from 'vitest';
import jwt from 'jsonwebtoken';

import { JWT_SECRET } from '../../lib/auth-secret.js';
import { generateToken, verifyToken } from '../../pages/api/auth-utils.js';

const ONE_DAY_IN_SECONDS = 24 * 60 * 60;

describe('pages/api/auth-utils generateToken', () => {
  it('issues a token whose lifetime is 24h (exp - iat === 86400)', () => {
    const token = generateToken({ id: 7, email: 'x@y.z', role: 'user' });
    const decoded = jwt.decode(token);
    expect(decoded.exp - decoded.iat).toBe(ONE_DAY_IN_SECONDS);
  });

  it('includes userId, email, and role in the payload from the user arg', () => {
    const token = generateToken({ id: 7, email: 'x@y.z', role: 'admin' });
    const decoded = jwt.decode(token);
    expect(decoded.userId).toBe(7);
    expect(decoded.email).toBe('x@y.z');
    expect(decoded.role).toBe('admin');
  });
});

describe('pages/api/auth-utils verifyToken', () => {
  it('returns the decoded payload for a valid token', () => {
    const token = generateToken({ id: 7, email: 'x@y.z', role: 'user' });
    const payload = verifyToken(token);
    expect(payload).not.toBeNull();
    expect(payload.userId).toBe(7);
    expect(payload.email).toBe('x@y.z');
    expect(payload.role).toBe('user');
  });

  it('returns null for a malformed token', () => {
    expect(verifyToken('not-a-jwt')).toBeNull();
  });

  it('returns null for a token signed with a different secret', () => {
    const token = jwt.sign(
      { userId: 7, email: 'x@y.z', role: 'user' },
      'some-other-secret',
      { expiresIn: '1h' }
    );
    expect(verifyToken(token)).toBeNull();
    expect(JWT_SECRET).not.toBe('some-other-secret');
  });
});
