import { describe, expect, it } from 'vitest';
import { parseSseChunk } from '../../src/api/sse';

describe('parseSseChunk', () => {
  it('parses named SSE events with JSON data and preserves remainder', () => {
    const result = parseSseChunk('', 'event: message_delta\ndata: {"text":"好的"}\n\npartial');

    expect(result.events).toEqual([{ type: 'message_delta', data: { text: '好的' } }]);
    expect(result.remainder).toBe('partial');
  });

  it('accumulates across multiple chunks', () => {
    const first = parseSseChunk('', 'event: message_delta\ndata: {"text":"好');

    expect(first.events).toEqual([]);
    expect(first.remainder).toBe('event: message_delta\ndata: {"text":"好');

    const second = parseSseChunk(first.remainder, '的"}\n\n');

    expect(second.events).toEqual([{ type: 'message_delta', data: { text: '好的' } }]);
    expect(second.remainder).toBe('');
  });

  it('handles multiple events in one chunk', () => {
    const result = parseSseChunk('', 'event: task_updated\ndata: {"taskId":"1"}\n\nevent: card_created\ndata: {"cardId":"c1"}\n\n');

    expect(result.events).toHaveLength(2);
    expect(result.events[0]).toEqual({ type: 'task_updated', data: { taskId: '1' } });
    expect(result.events[1]).toEqual({ type: 'card_created', data: { cardId: 'c1' } });
  });

  it('ignores malformed data events without throwing', () => {
    const result = parseSseChunk('', 'event: error\ndata: not-json\n\n');

    expect(result.events).toEqual([{ type: 'error', data: { message: 'SSE 数据解析失败' } }]);
  });

  it('skips events without both event and data lines', () => {
    const result = parseSseChunk('', 'event: something\n\n');

    expect(result.events).toEqual([]);
    expect(result.remainder).toBe('');
  });

  it('handles all six SSE event types', () => {
    const types = ['task_updated', 'message_delta', 'message_completed', 'card_created', 'error', 'completed'];

    for (const type of types) {
      const result = parseSseChunk('', `event: ${type}\ndata: {"key":"val"}\n\n`);
      expect(result.events[0].type).toBe(type);
    }
  });
});
