import { describe, it, expect } from 'vitest';
import {
  extractTextFromContent,
  normalizeContentBlocks,
  formatHistoryAsText,
  convertHistoryToMessages,
} from '@automaker/utils';
import { conversationHistoryFixture } from '../../fixtures/messages.js';

describe('conversation-utils.ts', () => {
  describe('extractTextFromContent', () => {
    it('should return string content as-is', () => {
      const result = extractTextFromContent('Hello world');
      expect(result).toBe('Hello world');
    });

    it('should extract text from single text block', () => {
      const content = [{ type: 'text', text: 'Hello' }];
      const result = extractTextFromContent(content);
      expect(result).toBe('Hello');
    });

    it('should extract and join multiple text blocks with newlines', () => {
      const content = [
        { type: 'text', text: 'First block' },
        { type: 'text', text: 'Second block' },
        { type: 'text', text: 'Third block' },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('First block\nSecond block\nThird block');
    });

    it('should ignore non-text blocks', () => {
      const content = [
        { type: 'text', text: 'Text content' },
        { type: 'image', source: { type: 'base64', data: 'abc' } },
        { type: 'text', text: 'More text' },
        { type: 'tool_use', name: 'bash', input: {} },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('Text content\nMore text');
    });

    it('should handle blocks without text property', () => {
      const content = [
        { type: 'text', text: 'Valid' },
        { type: 'text' } as any,
        { type: 'text', text: 'Also valid' },
      ];
      const result = extractTextFromContent(content);
      expect(result).toBe('Valid\n\nAlso valid');
    });

    it('should handle empty array', () => {
      const result = extractTextFromContent([]);
      expect(result).toBe('');
    });

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

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

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

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

  describe('formatHistoryAsText', () => {
    it('should return empty string for empty history', () => {
      const result = formatHistoryAsText([]);
      expect(result).toBe('');
    });

    it('should format single user message', () => {
      const history = [{ role: 'user' as const, content: 'Hello' }];
      const result = formatHistoryAsText(history);

      expect(result).toContain('Previous conversation:');
      expect(result).toContain('User: Hello');
      expect(result).toContain('---');
    });

    it('should format single assistant message', () => {
      const history = [{ role: 'assistant' as const, content: 'Hi there' }];
      const result = formatHistoryAsText(history);

      expect(result).toContain('Assistant: Hi there');
    });

    it('should format multiple messages with correct roles', () => {
      const history = conversationHistoryFixture.slice(0, 2);
      const result = formatHistoryAsText(history);

      expect(result).toContain('User: Hello, can you help me?');
      expect(result).toContain('Assistant: Of course! How can I assist you today?');
      expect(result).toContain('---');
    });

    it('should handle messages with array content (multipart)', () => {
      const history = [conversationHistoryFixture[2]]; // Has text + image
      const result = formatHistoryAsText(history);

      expect(result).toContain('What is in this image?');
      expect(result).not.toContain('base64'); // Should not include image data
    });

    it('should format all messages from fixture', () => {
      const result = formatHistoryAsText(conversationHistoryFixture);

      expect(result).toContain('Previous conversation:');
      expect(result).toContain('User: Hello, can you help me?');
      expect(result).toContain('Assistant: Of course!');
      expect(result).toContain('User: What is in this image?');
      expect(result).toContain('---');
    });

    it('should separate messages with double newlines', () => {
      const history = [
        { role: 'user' as const, content: 'First' },
        { role: 'assistant' as const, content: 'Second' },
      ];
      const result = formatHistoryAsText(history);

      expect(result).toMatch(/User: First\n\nAssistant: Second/);
    });
  });

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

    it('should convert single message to SDK format', () => {
      const history = [{ role: 'user' as const, 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 normalize string content to array', () => {
      const history = [{ role: 'assistant' as const, content: 'Response' }];
      const result = convertHistoryToMessages(history);

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

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

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

    it('should convert multiple messages', () => {
      const history = conversationHistoryFixture.slice(0, 2);
      const result = convertHistoryToMessages(history);

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

    it('should set correct fields for SDK format', () => {
      const history = [{ role: 'user' as const, content: 'Test' }];
      const result = convertHistoryToMessages(history);

      expect(result[0].session_id).toBe('');
      expect(result[0].parent_tool_use_id).toBeNull();
      expect(result[0].type).toBe('user');
      expect(result[0].message.role).toBe('user');
    });

    it('should handle all messages from fixture', () => {
      const result = convertHistoryToMessages(conversationHistoryFixture);

      expect(result).toHaveLength(3);
      expect(result[0].message.content).toBeInstanceOf(Array);
      expect(result[1].message.content).toBeInstanceOf(Array);
      expect(result[2].message.content).toBeInstanceOf(Array);
    });
  });
});
