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

// Mock postgresClient BEFORE importing the module under test.
const queryMock = vi.fn();
vi.mock('./postgres-client', () => ({
  postgresClient: {
    query: (...args: unknown[]) => queryMock(...args),
  },
}));

// eslint-disable-next-line import/first -- imported after vi.mock hoisting
import { writeAuditEvent } from './phishing-audit';

describe('writeAuditEvent', () => {
  beforeEach(() => {
    queryMock.mockReset();
  });

  it('issues one parameterized INSERT into audit_events and returns the RETURNING id when no client is passed', async () => {
    queryMock.mockResolvedValueOnce({ rows: [{ id: 'audit-1' }] });

    const id = await writeAuditEvent({
      campaignId: 'campaign-1',
      actor: 'operator@example.com',
      eventType: 'remediation_approved',
      payload: { actionType: 'block_sender' },
    });

    expect(id).toBe('audit-1');
    expect(queryMock).toHaveBeenCalledTimes(1);
    const [sql, params] = queryMock.mock.calls[0];
    expect(sql).toContain('INSERT INTO audit_events');
    expect(sql).toContain('RETURNING id::text AS id');
    expect(params).toEqual([
      'campaign-1',
      'operator@example.com',
      'remediation_approved',
      JSON.stringify({ actionType: 'block_sender' }),
    ]);
  });

  it('routes the query through an explicit client instead of postgresClient when one is supplied', async () => {
    const clientQueryMock = vi.fn().mockResolvedValueOnce({ rows: [{ id: 'audit-2' }] });
    const fakeClient = { query: clientQueryMock };

    const id = await writeAuditEvent(
      {
        campaignId: 'campaign-2',
        actor: null,
        eventType: 'remediation_completed',
        payload: { actionId: 'action-1' },
      },
      fakeClient
    );

    expect(id).toBe('audit-2');
    expect(clientQueryMock).toHaveBeenCalledTimes(1);
    expect(queryMock).not.toHaveBeenCalled();
  });
});
