// @vitest-environment jsdom

import '@testing-library/jest-dom/vitest';
import { cleanup, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { ChatTranscript } from '../../components/chat/ChatTranscript';
import { useStore } from '../../stores';
import type { ChatListItem, ContentBlock } from '../../stores/chat-types';

vi.mock('../../utils/screenshot', () => ({
  takeScreenshot: vi.fn(),
}));

const sessionPath = '/session/turn-time.jsonl';

function user(id: string, timestamp: number, text: string): ChatListItem {
  return {
    type: 'message',
    data: {
      id,
      role: 'user',
      timestamp,
      text,
      textHtml: `<p>${text}</p>`,
    },
  };
}

function assistant(id: string, timestamp: number, blocks: ContentBlock[]): ChatListItem {
  return {
    type: 'message',
    data: {
      id,
      role: 'assistant',
      timestamp,
      blocks,
    },
  };
}

function textBlock(text: string): ContentBlock {
  return { type: 'text', html: `<p>${text}</p>`, source: text };
}

function thinking(content: string): ContentBlock {
  return { type: 'thinking', content, sealed: true };
}

function interlude(id: string, text: string): ChatListItem {
  return {
    type: 'interlude',
    id,
    data: {
      type: 'interlude',
      id,
      variant: 'deferred_result',
      status: 'success',
      text,
    },
  };
}

describe('ChatTranscript turn timestamps', () => {
  beforeEach(() => {
    window.t = ((key: string) => ({
      'thinking.done': '思考完成',
      'common.regenerate': '重新生成',
    }[key] || key)) as typeof window.t;
    useStore.setState({
      agents: [],
      agentName: 'Hana',
      agentYuan: 'hana',
      streamingSessions: [],
      selectedIdsBySession: {},
      chatSessions: {
        [sessionPath]: {
          hasMore: false,
          loadingMore: false,
          items: [],
        },
      },
    } as never);
  });

  afterEach(() => {
    cleanup();
  });

  it('shows time on user messages and the final assistant message of each turn only', () => {
    const items: ChatListItem[] = [
      user('u1', new Date(2026, 4, 7, 8, 0).getTime(), '第一轮'),
      assistant('a1-tool', new Date(2026, 4, 7, 8, 1).getTime(), [thinking('读文件')]),
      assistant('a1-final', new Date(2026, 4, 7, 8, 2).getTime(), [textBlock('第一轮完成')]),
      user('u2', new Date(2026, 4, 7, 9, 0).getTime(), '第二轮'),
      assistant('a2-tool', new Date(2026, 4, 7, 9, 1).getTime(), [thinking('跑命令')]),
      assistant('a2-final', new Date(2026, 4, 7, 9, 2).getTime(), [textBlock('第二轮完成')]),
    ];

    render(
      <ChatTranscript
        items={items}
        sessionPath={sessionPath}
      />,
    );

    expect(screen.getByText('08:00')).toBeInTheDocument();
    expect(screen.queryByText('08:01')).not.toBeInTheDocument();
    expect(screen.getByText('08:02')).toBeInTheDocument();
    expect(screen.getByText('09:00')).toBeInTheDocument();
    expect(screen.queryByText('09:01')).not.toBeInTheDocument();
    expect(screen.getByText('09:02')).toBeInTheDocument();
  });

  it('renders interlude timeline items without an assistant message wrapper', () => {
    const { container } = render(
      <ChatTranscript
        items={[
          interlude('deferred:subagent-1:success', 'Hana 收到了后台回复'),
        ]}
        sessionPath={sessionPath}
      />,
    );

    expect(screen.getByText('Hana 收到了后台回复')).toBeInTheDocument();
    expect(container.querySelector('[data-interlude-status="success"]')).toBeInTheDocument();
    expect(container.querySelector('[data-message-id]')).toBeNull();
  });

  it('does not show a new assistant avatar only because an interlude sits between assistant messages', () => {
    render(
      <ChatTranscript
        items={[
          assistant('a1', new Date(2026, 4, 7, 8, 0).getTime(), [textBlock('前一段回复')]),
          interlude('deferred:subagent-2:success', '后台回复已抵达'),
          assistant('a2', new Date(2026, 4, 7, 8, 1).getTime(), [textBlock('继续接话')]),
        ]}
        sessionPath={sessionPath}
      />,
    );

    expect(screen.getByText('前一段回复')).toBeInTheDocument();
    expect(screen.getByText('后台回复已抵达')).toBeInTheDocument();
    expect(screen.getByText('继续接话')).toBeInTheDocument();
    expect(screen.getAllByText('Hana')).toHaveLength(1);
  });
});
