import { describe, expect, it } from 'vitest';

import {
  getSessionRefreshIntervalMs,
  getTaskCardMessageIndexes,
  mergeServerWithPendingUsers,
  shouldDisplayChatMessage,
  shouldMergePendingUsers,
} from '@/lib/chat-messages';
import type { ChatMessage } from '@/types';

describe('chat message helpers', () => {
  it('keeps pending local user messages after server refreshes', () => {
    const serverMessages: ChatMessage[] = [
      {
        role: 'assistant',
        content: 'Earlier answer',
        timestamp: '2026-05-21T08:00:00.000Z',
      },
    ];
    const localMessages: ChatMessage[] = [
      ...serverMessages,
      {
        role: 'user',
        content: 'Please continue',
        timestamp: '2026-05-21T08:01:00.000Z',
      },
    ];

    expect(mergeServerWithPendingUsers(serverMessages, localMessages)).toEqual([
      ...serverMessages,
      localMessages[1],
    ]);
  });

  it('does not duplicate local user messages already persisted by the server', () => {
    const serverMessages: ChatMessage[] = [
      {
        role: 'user',
        content: 'Please continue',
        timestamp: '2026-05-21T08:01:00.000Z',
      },
    ];
    const localMessages: ChatMessage[] = [
      {
        role: 'user',
        content: 'Please continue',
        timestamp: '2026-05-21T08:01:01.000Z',
      },
    ];

    expect(mergeServerWithPendingUsers(serverMessages, localMessages)).toEqual(serverMessages);
  });

  it('merges pending user messages when local state has an unpersisted trailing user turn', () => {
    const serverMessages: ChatMessage[] = [
      {
        role: 'assistant',
        content: 'Earlier answer',
        timestamp: '2026-05-21T08:00:00.000Z',
      },
    ];
    const localMessages: ChatMessage[] = [
      ...serverMessages,
      {
        role: 'user',
        content: 'Do this long task',
        timestamp: '2026-05-21T08:01:00.000Z',
      },
    ];

    expect(shouldMergePendingUsers(serverMessages, localMessages, false)).toBe(true);
  });

  it('shows a task card only on the latest assistant message for the same task', () => {
    const messages: ChatMessage[] = [
      {
        role: 'assistant',
        content: 'I will start.',
        run_id: 'run-1',
        task_id: 'task-1',
      },
      {
        role: 'assistant',
        content: 'I found data.',
        run_id: 'run-1',
        task_id: 'task-1',
      },
      {
        role: 'assistant',
        content: 'Final answer.',
        run_id: 'run-1',
        task_id: 'task-1',
        task_status: 'awaiting_acceptance',
      },
    ];

    expect(Array.from(getTaskCardMessageIndexes(messages))).toEqual([2]);
  });

  it('hides empty assistant records from session history', () => {
    expect(shouldDisplayChatMessage({ role: 'assistant', content: '', task_id: 'task-1', run_id: 'run-1' })).toBe(false);
    expect(shouldDisplayChatMessage({ role: 'assistant', content: '\u200B\uFEFF', task_id: 'task-1', run_id: 'run-1' })).toBe(false);
    expect(shouldDisplayChatMessage({ role: 'assistant', content: 'Final answer.', task_id: 'task-1', run_id: 'run-1' })).toBe(true);
    expect(shouldDisplayChatMessage({ role: 'user', content: '' })).toBe(true);
  });

  it('keeps polling idle visible chats so external channel messages appear', () => {
    expect(getSessionRefreshIntervalMs({ isLoading: true, isThinking: false, documentHidden: false })).toBe(1500);
    expect(getSessionRefreshIntervalMs({ isLoading: false, isThinking: true, documentHidden: false })).toBe(1500);
    expect(getSessionRefreshIntervalMs({ isLoading: false, isThinking: false, documentHidden: false })).toBe(5000);
    expect(getSessionRefreshIntervalMs({ isLoading: false, isThinking: false, documentHidden: true })).toBeNull();
  });
});
