// backend/tests/auth.test.ts
import request from 'supertest';
import express from 'express';
import authRouter from '../src/api/auth';
import { AuthService } from '../src/services/AuthService';
import { SessionService } from '../src/services/SessionService';
import { AuthLogger } from '../src/services/AuthLogger';

// Mock dependencies
jest.mock('../src/services/AuthService');
jest.mock('../src/services/SessionService');
jest.mock('../src/services/AuthLogger');

const app = express();
app.use(express.json());
app.use('/api/auth', authRouter);

describe('POST /api/auth/passphrase - Success Case', () => {
  beforeEach(() => {
    // Reset mocks before each test
    jest.clearAllMocks();
    (AuthService.validatePassphrase as jest.Mock).mockReturnValue(true);
    (SessionService.createSession as jest.Mock).mockReturnValue({ id: 'test-session-id', isAuthenticated: false, createdAt: new Date() });
    (SessionService.authenticateSession as jest.Mock).mockReturnValue(true);
  });

  it('should return 200 and a session token for a valid passphrase', async () => {
    const response = await request(app)
      .post('/api/auth/passphrase')
      .send({ passphrase: 'correct-passphrase' });

    expect(response.statusCode).toBe(200);
    expect(response.body.message).toBe('Authentication successful');
    expect(response.body.sessionToken).toBe('test-session-id');
    expect(AuthService.validatePassphrase).toHaveBeenCalledWith('correct-passphrase');
    expect(SessionService.createSession).toHaveBeenCalledTimes(1);
    expect(SessionService.authenticateSession).toHaveBeenCalledWith('test-session-id');
    expect(AuthLogger.logAttempt).toHaveBeenCalledWith('success', expect.any(String));
  });

  it('should return 400 if passphrase is not provided', async () => {
    const response = await request(app)
      .post('/api/auth/passphrase')
      .send({});

    expect(response.statusCode).toBe(400);
    expect(response.body.message).toBe('Passphrase is required.');
    expect(AuthService.validatePassphrase).not.toHaveBeenCalled();
    expect(SessionService.createSession).not.toHaveBeenCalled();
    expect(SessionService.authenticateSession).not.toHaveBeenCalled();
    expect(AuthLogger.logAttempt).toHaveBeenCalledWith('failure', expect.any(String));
  });

  it('should return 401 for an invalid passphrase', async () => {
    (AuthService.validatePassphrase as jest.Mock).mockReturnValue(false); // Simulate invalid passphrase

    const response = await request(app)
      .post('/api/auth/passphrase')
      .send({ passphrase: 'incorrect-passphrase' });

    expect(response.statusCode).toBe(401);
    expect(response.body.message).toBe('Invalid passphrase');
    expect(AuthService.validatePassphrase).toHaveBeenCalledWith('incorrect-passphrase');
    expect(SessionService.createSession).not.toHaveBeenCalled();
    expect(SessionService.authenticateSession).not.toHaveBeenCalled();
    expect(AuthLogger.logAttempt).toHaveBeenCalledWith('failure', expect.any(String));
  });
});
