const request = require('supertest');

jest.mock('../src/lib/prisma', () => require('./__mocks__/prisma'));
const prisma = require('../src/lib/prisma');
const app = require('../src/app');

const LOG = {
  id: 'ffffffff-0000-0000-0000-000000000001',
  table_name: 'experiments',
  record_id: 'aaaaaaaa-0000-0000-0000-000000000001',
  action: 'UPDATE',
  changes: { before: { title: 'Old' }, after: { title: 'New' } },
  timestamp: new Date().toISOString(),
};

beforeEach(() => jest.clearAllMocks());

describe('GET /api/audit-logs', () => {
  it('returns paginated logs', async () => {
    prisma.auditLog.findMany.mockResolvedValue([LOG]);
    prisma.auditLog.count.mockResolvedValue(1);

    const res = await request(app).get('/api/audit-logs');
    expect(res.status).toBe(200);
    expect(res.body.logs).toHaveLength(1);
    expect(res.body.total).toBe(1);
    expect(res.body.logs[0].action).toBe('UPDATE');
  });

  it('filters by tableName', async () => {
    prisma.auditLog.findMany.mockResolvedValue([LOG]);
    prisma.auditLog.count.mockResolvedValue(1);

    const res = await request(app).get('/api/audit-logs?tableName=experiments');
    expect(res.status).toBe(200);
    expect(prisma.auditLog.findMany).toHaveBeenCalledWith(
      expect.objectContaining({ where: { table_name: 'experiments' } })
    );
  });

  it('returns 422 for invalid tableName (not in allowlist)', async () => {
    const res = await request(app).get('/api/audit-logs?tableName=users');
    expect(res.status).toBe(422);
  });

  it('returns 422 for invalid recordId', async () => {
    const res = await request(app).get('/api/audit-logs?recordId=not-a-uuid');
    expect(res.status).toBe(422);
  });

  it('respects limit and offset params', async () => {
    prisma.auditLog.findMany.mockResolvedValue([]);
    prisma.auditLog.count.mockResolvedValue(0);

    const res = await request(app).get('/api/audit-logs?limit=10&offset=20');
    expect(res.status).toBe(200);
    expect(res.body.limit).toBe(10);
    expect(res.body.offset).toBe(20);
  });
});

describe('GET /api/audit-logs/:id', () => {
  it('returns a single log entry', async () => {
    prisma.auditLog.findUnique.mockResolvedValue(LOG);
    const res = await request(app).get(`/api/audit-logs/${LOG.id}`);
    expect(res.status).toBe(200);
    expect(res.body.action).toBe('UPDATE');
  });

  it('returns 404 for unknown log id', async () => {
    prisma.auditLog.findUnique.mockResolvedValue(null);
    const res = await request(app).get('/api/audit-logs/00000000-0000-0000-0000-000000000000');
    expect(res.status).toBe(404);
  });
});
