import { describe, it, expect } from 'vitest';
import type { ConversationMessage } from '@automaker/types';
import {
  extractTextFromContent,
  normalizeContentBlocks,
  formatHistoryAsText,
  convertHistoryToMessages,
} from '../src/conversation-utils';

describe('conversation-utils.ts', () => {
  describe('extractTextFromContent', () => {
    it('should extract text from string content', () => {
      const content = 'Hello, world!';
      const result = extractTextFromContent(content);
      expect(result).toBe('Hello, world!');
    });

    it('should extract text from array content with text blocks', () => {
      const content = [
        { type: 'text', text: 'First block' },
        { type: 'text', text: 'Second block' },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('First block\nSecond block');
    });

    it('should filter out non-text blocks', () => {
      const content = [
        { type: 'text', text: 'Text block' },
        { type: 'image', source: { data: '...' } },
        { type: 'text', text: 'Another text' },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('Text block\nAnother text');
    });

    it('should handle empty text blocks', () => {
      const content = [
        { type: 'text', text: 'First' },
        { type: 'text' },
        { type: 'text', text: 'Third' },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('First\n\nThird');
    });

    it('should return empty string for array with only non-text blocks', () => {
      const content = [
        { type: 'image', source: {} },
        { type: 'tool_use', source: {} },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('');
    });

    it('should return empty string for empty array', () => {
      const content: Array<{ type: string; text?: string }> = [];
      const result = extractTextFromContent(content);
      expect(result).toBe('');
    });
  });

  describe('normalizeContentBlocks', () => {
    it('should convert string to array of text blocks', () => {
      const content = 'Simple text';
      const result = normalizeContentBlocks(content);
      expect(result).toEqual([{ type: 'text', text: 'Simple text' }]);
    });

    it('should return array as-is', () => {
      const content = [
        { type: 'text', text: 'First' },
        { type: 'image', source: {} },
      ];
      const result = normalizeContentBlocks(content);
      expect(result).toBe(content);
      expect(result).toEqual(content);
    });

    it('should handle empty string', () => {
      const content = '';
      const result = normalizeContentBlocks(content);
      expect(result).toEqual([{ type: 'text', text: '' }]);
    });

    it('should handle multiline string', () => {
      const content = 'Line 1\nLine 2\nLine 3';
      const result = normalizeContentBlocks(content);
      expect(result).toEqual([{ type: 'text', text: 'Line 1\nLine 2\nLine 3' }]);
    });
  });

  describe('formatHistoryAsText', () => {
    it('should format empty history as empty string', () => {
      const history: ConversationMessage[] = [];
      const result = formatHistoryAsText(history);
      expect(result).toBe('');
    });

    it('should format single user message', () => {
      const history: ConversationMessage[] = [{ role: 'user', content: 'Hello!' }];
      const result = formatHistoryAsText(history);
      expect(result).toBe('Previous conversation:\n\nUser: Hello!\n\n---\n\n');
    });

    it('should format single assistant message', () => {
      const history: ConversationMessage[] = [{ role: 'assistant', content: 'Hi there!' }];
      const result = formatHistoryAsText(history);
      expect(result).toBe('Previous conversation:\n\nAssistant: Hi there!\n\n---\n\n');
    });

    it('should format conversation with multiple messages', () => {
      const history: ConversationMessage[] = [
        { role: 'user', content: "What's 2+2?" },
        { role: 'assistant', content: 'The answer is 4.' },
        { role: 'user', content: 'Thanks!' },
      ];
      const result = formatHistoryAsText(history);
      expect(result).toBe(
        'Previous conversation:\n\n' +
          "User: What's 2+2?\n\n" +
          'Assistant: The answer is 4.\n\n' +
          'User: Thanks!\n\n' +
          '---\n\n'
      );
    });

    it('should handle array content by extracting text', () => {
      const history: ConversationMessage[] = [
        {
          role: 'user',
          content: [
            { type: 'text', text: 'First part' },
            { type: 'text', text: 'Second part' },
          ],
        },
      ];
      const result = formatHistoryAsText(history);
      expect(result).toBe('Previous conversation:\n\nUser: First part\nSecond part\n\n---\n\n');
    });

    it('should handle mixed string and array content', () => {
      const history: ConversationMessage[] = [
        { role: 'user', content: 'String message' },
        {
          role: 'assistant',
          content: [{ type: 'text', text: 'Array message' }],
        },
      ];
      const result = formatHistoryAsText(history);
      expect(result).toContain('User: String message');
      expect(result).toContain('Assistant: Array message');
    });
  });

  describe('convertHistoryToMessages', () => {
    it('should convert empty history', () => {
      const history: ConversationMessage[] = [];
      const result = convertHistoryToMessages(history);
      expect(result).toEqual([]);
    });

    it('should convert single user message', () => {
      const history: ConversationMessage[] = [{ role: 'user', content: 'Hello!' }];
      const result = convertHistoryToMessages(history);

      expect(result).toHaveLength(1);
      expect(result[0]).toMatchObject({
        type: 'user',
        session_id: '',
        message: {
          role: 'user',
          content: [{ type: 'text', text: 'Hello!' }],
        },
        parent_tool_use_id: null,
      });
    });

    it('should convert single assistant message', () => {
      const history: ConversationMessage[] = [{ role: 'assistant', content: 'Hi there!' }];
      const result = convertHistoryToMessages(history);

      expect(result).toHaveLength(1);
      expect(result[0]).toMatchObject({
        type: 'assistant',
        session_id: '',
        message: {
          role: 'assistant',
          content: [{ type: 'text', text: 'Hi there!' }],
        },
        parent_tool_use_id: null,
      });
    });

    it('should preserve array content as-is', () => {
      const content = [
        { type: 'text', text: 'Text' },
        { type: 'image', source: { data: '...' } },
      ];
      const history: ConversationMessage[] = [{ role: 'user', content }];
      const result = convertHistoryToMessages(history);

      expect(result[0].message.content).toEqual(content);
    });

    it('should convert multiple messages', () => {
      const history: ConversationMessage[] = [
        { role: 'user', content: 'First' },
        { role: 'assistant', content: 'Second' },
        { role: 'user', content: 'Third' },
      ];
      const result = convertHistoryToMessages(history);

      expect(result).toHaveLength(3);
      expect(result[0].type).toBe('user');
      expect(result[1].type).toBe('assistant');
      expect(result[2].type).toBe('user');
    });

    it('should set session_id to empty string', () => {
      const history: ConversationMessage[] = [{ role: 'user', content: 'Test' }];
      const result = convertHistoryToMessages(history);

      expect(result[0].session_id).toBe('');
    });

    it('should set parent_tool_use_id to null', () => {
      const history: ConversationMessage[] = [{ role: 'user', content: 'Test' }];
      const result = convertHistoryToMessages(history);

      expect(result[0].parent_tool_use_id).toBeNull();
    });

    it('should normalize string content to blocks', () => {
      const history: ConversationMessage[] = [{ role: 'user', content: 'String content' }];
      const result = convertHistoryToMessages(history);

      expect(result[0].message.content).toEqual([{ type: 'text', text: 'String content' }]);
    });
  });
});
