import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom';
import TorrentDetail from './TorrentDetail';
import * as torrentApi from '../api/torrent';
import * as torrentCommentApi from '../api/torrentComment';

// Mock API 模块
jest.mock('../api/torrent');
jest.mock('../api/torrentComment');

// Mock useLocation 钩子
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useLocation: jest.fn(),
}));

describe('TorrentDetail 组件', () => {
  const mockTorrent = {
    id: '1',
    torrentName: '测试种子',
    category: '电影',
    region: '美国',
    resolution: '1080P',
    subtitle: '中文字幕',
    username: 'user1',
    createTime: '2023-01-01T00:00:00Z',
    likeCount: 5,
    replyCount: 3,
    description: '这是一个测试种子描述',
  };

  const mockComments = [
    {
      id: 'c1',
      content: '测试评论1',
      authorId: 'user2',
      createTime: '2023-01-01T01:00:00Z',
      likeCount: 2,
      replies: [
        {
          id: 'c1r1',
          content: '测试回复1',
          authorId: 'user3',
          createTime: '2023-01-01T02:00:00Z',
          likeCount: 1,
        }
      ]
    }
  ];

  beforeEach(() => {
    // 设置模拟的 API 响应
    torrentApi.getTorrentDetail.mockResolvedValue({
      data: {
        code: 200,
        data: {
          torrent: mockTorrent,
          comments: mockComments,
        }
      }
    });

    torrentApi.likeTorrent.mockResolvedValue({ data: { code: 200 } });
    torrentApi.addTorrentComment.mockResolvedValue({ data: { code: 200 } });
    torrentCommentApi.likeTorrentComment.mockResolvedValue({ data: { code: 200 } });
    torrentCommentApi.addCommentReply.mockResolvedValue({ data: { code: 200 } });

    // 模拟 useLocation
    useLocation.mockReturnValue({
      state: { fromTab: 'share' }
    });

    // 设置 localStorage
    Storage.prototype.getItem = jest.fn((key) => {
      if (key === 'username') return 'testuser';
      return null;
    });
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  const renderComponent = () => {
    return render(
      <MemoryRouter initialEntries={['/torrent/1']}>
        <Routes>
          <Route path="/torrent/:id" element={<TorrentDetail />} />
        </Routes>
      </MemoryRouter>
    );
  };

  it('应该正确加载和显示种子详情', async () => {
    renderComponent();

    // 检查加载状态
    expect(screen.getByText('加载中...')).toBeInTheDocument();

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('测试种子')).toBeInTheDocument();
      expect(screen.getByText('这是一个测试种子描述')).toBeInTheDocument();
      expect(screen.getByText('user1')).toBeInTheDocument();
    });
  });

  it('应该能够点赞种子', async () => {
    renderComponent();

    await waitFor(() => {
      expect(screen.getByText('测试种子')).toBeInTheDocument();
    });

    fireEvent.click(screen.getByText(/点赞 \(5\)/));

    await waitFor(() => {
      expect(torrentApi.likeTorrent).toHaveBeenCalledWith('1');
    });
  });

  it('应该能够提交评论', async () => {
    renderComponent();

    await waitFor(() => {
      expect(screen.getByText('测试种子')).toBeInTheDocument();
    });

    const commentInput = screen.getByPlaceholderText('写下你的评论...');
    fireEvent.change(commentInput, { target: { value: '新评论' } });
    fireEvent.click(screen.getByText('发表评论'));

    await waitFor(() => {
      expect(torrentApi.addTorrentComment).toHaveBeenCalledWith('1', {
        content: '新评论',
        authorId: 'testuser'
      });
    });
  });

  it('应该能够点赞评论', async () => {
    renderComponent();

    await waitFor(() => {
      expect(screen.getByText('测试评论1')).toBeInTheDocument();
    });

    fireEvent.click(screen.getAllByText(/👍 \(2\)/)[0]);

    await waitFor(() => {
      expect(torrentCommentApi.likeTorrentComment).toHaveBeenCalledWith('c1');
    });
  });

  it('应该能够返回资源区', async () => {
    const { container } = renderComponent();

    await waitFor(() => {
      expect(screen.getByText('测试种子')).toBeInTheDocument();
    });

    const backButton = container.querySelector('.back-button');
    fireEvent.click(backButton);

    // 这里可以添加导航验证，但需要更复杂的路由设置
  });
});