import { fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import {
  ChatCommandRenameDialog,
  ChatCommandTimelineDialog,
  type ChatTimelineEntry,
} from '@/pages/Chat/ChatCommandDialogs';

const entries: ChatTimelineEntry[] = [
  { messageId: 'user-1', role: 'user', label: 'User', preview: 'First prompt' },
  {
    messageId: 'assistant-1',
    role: 'assistant',
    label: 'Assistant',
    preview: 'First answer',
  },
];

describe('ChatCommandDialogs', () => {
  it('submits a trimmed controlled rename and rejects a whitespace-only title', () => {
    const onTitleChange = vi.fn();
    const onSubmit = vi.fn();
    const onCancel = vi.fn();
    const { rerender } = render(
      <ChatCommandRenameDialog
        open
        title="  New title  "
        onTitleChange={onTitleChange}
        onSubmit={onSubmit}
        onCancel={onCancel}
      />,
    );

    expect(screen.getByRole('textbox', { name: '会话标题' })).toHaveFocus();
    fireEvent.keyDown(screen.getByRole('textbox', { name: '会话标题' }), {
      key: 'Escape',
    });
    expect(onCancel).toHaveBeenCalledOnce();
    fireEvent.click(screen.getByRole('button', { name: '重命名' }));
    expect(onSubmit).toHaveBeenCalledWith('New title');

    rerender(
      <ChatCommandRenameDialog
        open
        title="   "
        onTitleChange={onTitleChange}
        onSubmit={onSubmit}
        onCancel={onCancel}
      />,
    );

    expect(screen.getByRole('button', { name: '重命名' })).toBeDisabled();
  });

  it('returns the exact selected message for timeline navigation and fork modes', () => {
    const onSelect = vi.fn();
    const { rerender } = render(
      <ChatCommandTimelineDialog
        open
        mode="timeline"
        entries={entries}
        onSelect={onSelect}
        onCancel={vi.fn()}
      />,
    );

    fireEvent.click(screen.getByRole('button', { name: /First answer/ }));
    expect(onSelect).toHaveBeenLastCalledWith('assistant-1');

    rerender(
      <ChatCommandTimelineDialog
        open
        mode="fork"
        entries={entries}
        onSelect={onSelect}
        onCancel={vi.fn()}
      />,
    );

    expect(
      screen.getByRole('heading', { name: '选择分叉位置' }),
    ).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: /First prompt/ }));
    expect(onSelect).toHaveBeenLastCalledWith('user-1');
  });

  it('contains timeline focus and restores the previously focused control', () => {
    const onCancel = vi.fn();
    const { rerender } = render(
      <>
        <textarea aria-label="Composer" />
        <ChatCommandTimelineDialog
          open={false}
          mode="timeline"
          entries={entries}
          onSelect={vi.fn()}
          onCancel={onCancel}
        />
      </>,
    );
    const composer = screen.getByRole('textbox', { name: 'Composer' });
    composer.focus();

    rerender(
      <>
        <textarea aria-label="Composer" />
        <ChatCommandTimelineDialog
          open
          mode="timeline"
          entries={entries}
          onSelect={vi.fn()}
          onCancel={onCancel}
        />
      </>,
    );

    const firstEntry = screen.getByRole('button', { name: /First prompt/ });
    const cancel = screen.getByRole('button', { name: '取消' });
    expect(firstEntry).toHaveFocus();

    fireEvent.keyDown(firstEntry, { key: 'Tab', shiftKey: true });
    expect(cancel).toHaveFocus();
    fireEvent.keyDown(cancel, { key: 'Tab' });
    expect(firstEntry).toHaveFocus();
    fireEvent.keyDown(firstEntry, { key: 'Escape' });
    expect(onCancel).toHaveBeenCalledOnce();

    rerender(
      <>
        <textarea aria-label="Composer" />
        <ChatCommandTimelineDialog
          open={false}
          mode="timeline"
          entries={entries}
          onSelect={vi.fn()}
          onCancel={onCancel}
        />
      </>,
    );
    expect(composer).toHaveFocus();
  });
});
