
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import CreatePost from '../pages/Forum/posts-create/CreatePost';
import axios from 'axios';

// mock axios
jest.mock('axios');

describe('CreatePost Component', () => {
  const mockUserId = 123;

  beforeEach(() => {
    axios.post.mockClear();
  });

  test('renders form inputs and button', () => {
    render(<CreatePost user_id={mockUserId} />);

    expect(screen.getByLabelText(/标题/)).toBeInTheDocument();
    expect(screen.getByLabelText(/内容/)).toBeInTheDocument();
    expect(screen.getByLabelText(/图片链接/)).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '发布' })).toBeInTheDocument();
  });

  test('shows error when title and content are empty', async () => {
    render(<CreatePost user_id={mockUserId} />);

    fireEvent.click(screen.getByRole('button', { name: '发布' }));

    expect(await screen.findByText('标题和内容不能为空')).toBeInTheDocument();
  });

  test('submits post and shows success message', async () => {
    axios.post.mockResolvedValueOnce({
      data: { post_id: 456 },
    });

    render(<CreatePost user_id={mockUserId} />);

    fireEvent.change(screen.getByLabelText(/标题/), {
      target: { value: '测试标题' },
    });
    fireEvent.change(screen.getByLabelText(/内容/), {
      target: { value: '测试内容' },
    });
    fireEvent.change(screen.getByLabelText(/图片链接/), {
      target: { value: 'http://example.com/image.jpg' },
    });

    fireEvent.click(screen.getByRole('button', { name: '发布' }));

    await waitFor(() =>
      expect(axios.post).toHaveBeenCalledWith(
        `/echo/forum/posts/${mockUserId}/createPost`,
        {
          title: '测试标题',
          post_content: '测试内容',
          image_url: 'http://example.com/image.jpg',
        }
      )
    );

    expect(await screen.findByText(/发帖成功，帖子ID：456/)).toBeInTheDocument();
  });

  test('shows error message on submission failure', async () => {
    axios.post.mockRejectedValueOnce({
      response: {
        data: {
          error: '服务器内部错误',
        },
      },
    });

    render(<CreatePost user_id={mockUserId} />);

    fireEvent.change(screen.getByLabelText(/标题/), {
      target: { value: '测试标题' },
    });
    fireEvent.change(screen.getByLabelText(/内容/), {
      target: { value: '测试内容' },
    });

    fireEvent.click(screen.getByRole('button', { name: '发布' }));

    expect(await screen.findByText('服务器内部错误')).toBeInTheDocument();
  });

  test('shows fallback error message when no response', async () => {
    axios.post.mockRejectedValueOnce(new Error('Network error'));

    render(<CreatePost user_id={mockUserId} />);

    fireEvent.change(screen.getByLabelText(/标题/), {
      target: { value: '测试标题' },
    });
    fireEvent.change(screen.getByLabelText(/内容/), {
      target: { value: '测试内容' },
    });

    fireEvent.click(screen.getByRole('button', { name: '发布' }));

    expect(await screen.findByText('发帖失败，请稍后重试')).toBeInTheDocument();
  });
});
