import { describe, it, expect, beforeEach } from 'vitest';
import { promises as fs } from 'fs';
import path from 'path';
import crypto from 'crypto';
import {
  appendPhaseUpdate,
  getPendingPhaseUpdates,
  markPhaseUpdateSent,
  getAllPhaseUpdates,
  type PhaseUpdateEvent
} from '../PhaseUpdateQueue.js';

// Use a unique phase namespace to avoid interference from parallel tests
const TEST_NAMESPACE = `test-${crypto.randomUUID()}`;

const TEST_QUEUE_FILE = path.join(process.cwd(), 'status/phase-updates.jsonl');

describe('PhaseUpdateQueue', () => {
  beforeEach(async () => {
    try {
      await fs.unlink(TEST_QUEUE_FILE);
    } catch {}
  });

  it('appends events and retrieves pending only', async () => {
    const phaseName = `phase-${TEST_NAMESPACE}`;
    let ev1 = await appendPhaseUpdate({ eventType: 'phase_started', phase: phaseName, summary: 'Import started' });
    let ev2 = await appendPhaseUpdate({ eventType: 'phase_failed', phase: phaseName, summary: 'Import failed', details: 'Network error' });
    expect(ev1.id).toBeDefined();
    expect(ev2.id).toBeDefined();

    const pending = await getPendingPhaseUpdates();
    const ours = pending.filter((e: PhaseUpdateEvent) => e.phase === phaseName);
    expect(ours.length).toBe(2);
    expect(ours.map(e => e.id)).toContain(ev1.id);
    expect(ours.some(e => e.eventType === 'phase_failed')).toBe(true);
  });

  it('markPhaseUpdateSent updates relayStatus', async () => {
    const phaseName = `phase-${TEST_NAMESPACE}`;
    let ev = await appendPhaseUpdate({ eventType: 'phase_succeeded', phase: phaseName, summary: 'Parsed recipe' });
    let id = ev.id;
    let result = await markPhaseUpdateSent(id);
    expect(result).toBe(true);
    let pendingAfter = await getPendingPhaseUpdates();
    expect(pendingAfter.find((e: PhaseUpdateEvent) => e.phase === phaseName && e.id === id)).toBeUndefined();
    let all = await getAllPhaseUpdates();
    expect(all.find((e: PhaseUpdateEvent) => e.id === id)?.relayStatus).toBe('sent');
  });

  it('getAllPhaseUpdates reads back all events', async () => {
    const phaseName = `phase-${TEST_NAMESPACE}`;
    await appendPhaseUpdate({ eventType: 'phase_started', phase: phaseName, summary: 'Phase A started' });
    await appendPhaseUpdate({ eventType: 'phase_started', phase: phaseName, summary: 'Phase B started' });
    const all = await getAllPhaseUpdates();
    const ours = all.filter((e: PhaseUpdateEvent) => e.phase === phaseName);
    expect(ours.length).toBeGreaterThanOrEqual(2);
  });
});
