import { render, screen } from '@testing-library/react';
import { test, expect, beforeEach, vi } from 'vitest';
import App from '../src/App';
import userEvent from '@testing-library/user-event';
import { waitFor } from '@testing-library/react';
import { listDocuments, getDocument, search } from '../src/api/client';

vi.mock('../src/api/client');

vi.mock('@monaco-editor/react', () => ({
  default: ({ value, onChange }: { value: string; onChange: (value: string | undefined) => void }) => (
    <textarea
      data-testid="monaco-editor-mock"
      value={value}
      onChange={(e) => onChange(e.target.value)}
    />
  ),
}));

beforeEach(() => {
  vi.mocked(listDocuments).mockReset();
  vi.mocked(getDocument).mockReset();
  vi.mocked(search).mockReset();
  vi.mocked(listDocuments).mockResolvedValue({ folders: [], files: [] });
  vi.mocked(getDocument).mockResolvedValue({
    key: '',
    content: '',
    contentType: 'text/markdown',
  });
  vi.mocked(search).mockResolvedValue({ results: [] });
});

test('renders the DocHub heading', () => {
  render(<App />);
  expect(screen.getByRole('heading', { name: 'DocHub' })).toBeInTheDocument();
});

test('shows an empty state and a file tree when no document is selected', async () => {
  vi.mocked(listDocuments).mockResolvedValue({
    folders: [],
    files: [{ key: '产品文档/架构设计.md', name: '架构设计.md', size: 100, modifiedAt: '2026-08-01T10:00:00Z' }],
  });

  render(<App />);

  expect(screen.getByTestId('empty-state')).toBeInTheDocument();
  expect(await screen.findByText('架构设计.md')).toBeInTheDocument();
});

test('selecting a file from the tree loads it into the editor', async () => {
  vi.mocked(listDocuments).mockResolvedValue({
    folders: [],
    files: [{ key: '产品文档/架构设计.md', name: '架构设计.md', size: 100, modifiedAt: '2026-08-01T10:00:00Z' }],
  });
  vi.mocked(getDocument).mockResolvedValue({
    key: '产品文档/架构设计.md',
    content: '# 架构设计',
    contentType: 'text/markdown',
  });
  const user = userEvent.setup();

  render(<App />);

  const fileRow = await screen.findByText('架构设计.md');
  await user.click(fileRow);

  const textarea = await screen.findByTestId('monaco-editor-mock');
  expect(textarea).toHaveValue('# 架构设计');
});

test('searching shows the results overlay, and clicking a result opens the document', async () => {
  vi.mocked(listDocuments).mockResolvedValue({ folders: [], files: [] });
  vi.mocked(search).mockResolvedValue({
    results: [{ key: '产品文档/架构设计.md', title: '架构设计.md', path: '产品文档', snippet: '...<em>检索</em>...' }],
  });
  vi.mocked(getDocument).mockResolvedValue({
    key: '产品文档/架构设计.md',
    content: '# 架构设计',
    contentType: 'text/markdown',
  });
  const user = userEvent.setup();

  render(<App />);

  const searchInput = screen.getByRole('textbox', { name: '搜索文档' });
  await user.type(searchInput, '检索');

  await waitFor(
    () => {
      expect(screen.getByTestId('search-result-产品文档/架构设计.md')).toBeInTheDocument();
    },
    { timeout: 1000 }
  );

  await user.click(screen.getByTestId('search-result-产品文档/架构设计.md'));

  await waitFor(() => {
    expect(screen.queryByTestId('search-results')).not.toBeInTheDocument();
  });
  const textarea = await screen.findByTestId('monaco-editor-mock');
  expect(textarea).toHaveValue('# 架构设计');
});
