import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi, test, expect, beforeEach } from 'vitest';
import UploadButton from '../../src/components/UploadButton';
import { uploadDocument } from '../../src/api/client';

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

beforeEach(() => {
  vi.mocked(uploadDocument).mockReset();
});

test('opens the upload modal when the button is clicked', async () => {
  const user = userEvent.setup();
  render(<UploadButton path="产品文档" onUploaded={vi.fn()} />);

  expect(screen.queryByTestId('upload-modal')).not.toBeInTheDocument();

  await user.click(screen.getByRole('button', { name: '上传文档' }));

  expect(screen.getByTestId('upload-modal')).toBeInTheDocument();
});

test('selecting a file through the hidden input uploads it', async () => {
  vi.mocked(uploadDocument).mockResolvedValue({ key: '产品文档/新文档.md', name: '新文档.md', size: 42 });
  const onUploaded = vi.fn();
  const user = userEvent.setup();

  render(<UploadButton path="产品文档" onUploaded={onUploaded} />);
  await user.click(screen.getByRole('button', { name: '上传文档' }));

  const file = new File(['# 新文档'], '新文档.md', { type: 'text/markdown' });
  const input = screen.getByTestId('upload-file-input');
  await user.upload(input, file);

  expect(uploadDocument).toHaveBeenCalledWith(file, '产品文档');
  await waitFor(() => {
    expect(onUploaded).toHaveBeenCalledWith({ key: '产品文档/新文档.md', name: '新文档.md', size: 42 });
  });
});

test('dropping a file onto the dropzone uploads it', async () => {
  vi.mocked(uploadDocument).mockResolvedValue({ key: '产品文档/拖拽文档.md', name: '拖拽文档.md', size: 10 });
  const onUploaded = vi.fn();
  const user = userEvent.setup();

  render(<UploadButton path="产品文档" onUploaded={onUploaded} />);
  await user.click(screen.getByRole('button', { name: '上传文档' }));

  const file = new File(['内容'], '拖拽文档.md', { type: 'text/markdown' });
  const dropzone = screen.getByTestId('dropzone');

  fireEvent.drop(dropzone, {
    dataTransfer: { files: [file] },
  });

  expect(uploadDocument).toHaveBeenCalledWith(file, '产品文档');
  await waitFor(() => {
    expect(onUploaded).toHaveBeenCalledWith({ key: '产品文档/拖拽文档.md', name: '拖拽文档.md', size: 10 });
  });
});
