import React from 'react';
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import { MemoryRouter, useNavigate, useLocation } from 'react-router-dom';
import Exchange from './Exchange';
import { 
  generateInviteCode, 
  getUserInviteCodes, 
  exchangeUpload, 
  getUserInfo 
} from '../../api/personal';

// Mock API 调用
jest.mock('../../api/personal', () => ({
  generateInviteCode: jest.fn(),
  getUserInviteCodes: jest.fn(),
  exchangeUpload: jest.fn(),
  getUserInfo: jest.fn()
}));

// Mock react-router-dom hooks
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useNavigate: jest.fn(),
  useLocation: jest.fn()
}));

describe('Exchange Component', () => {
  const mockNavigate = jest.fn();
  const mockLocation = {
    pathname: '/personal/exchange',
    state: { dashboardTab: 'exchange' }
  };

  const mockUserInfo = {
    magicPoints: 100,
    username: 'testuser'
  };

  const mockInviteCodes = [
    { code: 'ABCD-1234', isUsed: false },
    { code: 'EFGH-5678', isUsed: true }
  ];

  beforeEach(() => {
    useNavigate.mockReturnValue(mockNavigate);
    useLocation.mockReturnValue(mockLocation);
    jest.clearAllMocks();
    
    // 设置默认 mock 返回值
    getUserInfo.mockResolvedValue(mockUserInfo);
    getUserInviteCodes.mockResolvedValue(mockInviteCodes);
    generateInviteCode.mockResolvedValue({ code: 'NEW-CODE', isUsed: false });
    exchangeUpload.mockResolvedValue({ success: true });
  });

  it('应该正确加载并显示用户信息和邀请码', async () => {
    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    // 初始加载状态
    expect(screen.getByText('加载中...')).toBeInTheDocument();

    // 等待数据加载完成
    await waitFor(() => {
      expect(screen.getByText('兑换区')).toBeInTheDocument();
      expect(screen.getByText('当前魔力值: 100')).toBeInTheDocument();
      expect(screen.getByText('ABCD-1234')).toBeInTheDocument();
      expect(screen.getByText('EFGH-5678')).toBeInTheDocument();
      expect(screen.getByText('可用')).toBeInTheDocument();
      expect(screen.getByText('已使用')).toBeInTheDocument();
    });
  });

  it('应该处理生成邀请码操作', async () => {
    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      // 使用更精确的选择器定位按钮
      const generateButtons = screen.getAllByRole('button', { name: '兑换邀请码' });
      // 选择第一个按钮（或根据实际情况选择正确的按钮）
      fireEvent.click(generateButtons[0]);
    });

    expect(generateInviteCode).toHaveBeenCalled();
    await waitFor(() => {
      expect(getUserInfo).toHaveBeenCalledTimes(2); // 初始加载 + 生成后刷新
    });
  });

  it('应该处理兑换上传量操作', async () => {
    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      const input = screen.getByPlaceholderText('输入要兑换的魔力值');
      const exchangeButton = screen.getByRole('button', { name: '兑换上传量' });
      
      // 输入有效值
      fireEvent.change(input, { target: { value: '50' } });
      fireEvent.click(exchangeButton);
    });

    expect(exchangeUpload).toHaveBeenCalledWith(50);
    await waitFor(() => {
      expect(getUserInfo).toHaveBeenCalledTimes(2); // 初始加载 + 兑换后刷新
    });
  });
  

  it('应该处理返回按钮点击', async () => {
    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      const backButton = screen.getByText(/返回个人中心/);
      fireEvent.click(backButton);
      
      expect(mockNavigate).toHaveBeenCalledWith('/personal', {
        state: {
          fromSubpage: true,
          dashboardTab: 'exchange'
        },
        replace: true
      });
    });
  });

  it('应该显示错误信息当API调用失败', async () => {
    getUserInfo.mockRejectedValueOnce(new Error('获取用户信息失败'));

    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      expect(screen.getByText('错误: 获取用户信息失败')).toBeInTheDocument();
    });
  });

  it('应该禁用兑换按钮当魔力值不足', async () => {
    getUserInfo.mockResolvedValueOnce({ magicPoints: 5 }); // 设置魔力值不足

    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      const inviteButtons = screen.getAllByRole('button', { name: '兑换邀请码' });
      expect(inviteButtons[0]).toBeDisabled();
    });
  });

  it('应该正确处理空邀请码列表', async () => {
    getUserInviteCodes.mockResolvedValueOnce([]);

    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    await waitFor(() => {
      expect(screen.queryByText('我的邀请码')).not.toBeInTheDocument();
    });
  });

  it('应该显示加载状态', async () => {
    // 延迟API响应以测试加载状态
    getUserInfo.mockImplementation(() => new Promise(() => {}));

    render(
      <MemoryRouter>
        <Exchange />
      </MemoryRouter>
    );

    expect(screen.getByText('加载中...')).toBeInTheDocument();
  });
});