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

const { readMock, pendingMock } = vi.hoisted(() => ({
  readMock: vi.fn(),
  pendingMock: vi.fn(),
}));

vi.mock('../../src/backend/services/WorkflowStatusManager', () => ({
  WorkflowStatusManager: vi.fn().mockImplementation(() => ({
    read: readMock,
  })),
}));

vi.mock('../../src/backend/services/PhaseUpdateQueue', () => ({
  getPendingPhaseUpdates: pendingMock,
}));

import main from '../morning-report';

describe('morning-report', () => {
  let consoleSpy: any;

  beforeEach(() => {
    vi.clearAllMocks();
    consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
  });

  afterEach(() => {
    consoleSpy.mockRestore();
  });

  it('detects stalled workflow and formats report', async () => {
    const now = new Date('2026-03-26T18:00:00.000Z');
    readMock.mockResolvedValue({
      currentPhase: 'parse',
      overallStatus: 'running',
      lastUpdated: '2026-03-26T16:00:00.000Z',
      lastFailureReason: null,
      nextAction: '',
      completedPhases: ['a'],
    });
    pendingMock.mockResolvedValue([
      {
        id: 'foo',
        eventType: 'phase_started',
        phase: 'parse',
        timestamp: '2026-03-26T16:00:00.000Z',
        summary: 'Phase parse started',
        relayStatus: 'pending',
      },
    ]);
    await main({
      commitWindowHours: 24,
      stalledThresholdMinutes: 60,
      now,
      getRecentCommitsFn: async () => [
        { hash: 'abc123', msg: 'test commit', date: '2026-03-26T10:00:00.000Z' },
      ],
    });

    const output = consoleSpy.mock.calls[0][0] as string;
    expect(output).toContain('⚠️ Workflow Stalled');
    expect(output).toContain('abc123');
    expect(output).toContain('[phase_started]');
    expect(output).toContain('[id: foo]');
  });

  it('shows empty/no-status states', async () => {
    const now = new Date('2026-03-26T11:00:00.000Z');
    readMock.mockResolvedValue(null);
    pendingMock.mockResolvedValue([]);
    await main({
      commitWindowHours: 24,
      stalledThresholdMinutes: 60,
      now,
      getRecentCommitsFn: async () => [],
    });

    const output = consoleSpy.mock.calls[0][0] as string;
    expect(output).toContain('(No commits in window)');
    expect(output).toContain('No workflow status available');
    expect(output).toContain('All phase updates relayed');
  });
});
