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();
  });
});