import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { BrowserRouter } from 'react-router-dom';
import { AuthProvider } from '../contexts/AuthContext';
import { NotificationProvider } from '../contexts/NotificationContext';
import CouponCard from '../components/CouponCard';
import StatsCard from '../components/StatsCard';
import InviteModal from '../components/InviteModal';
import UserDashboard from '../pages/UserDashboard';

// Mock API responses
const mockResponses = {
  coupons: [
    {
      id: '1',
      name: '新用户专享优惠券',
      description: '满100减10元',
      discount: 10.00,
      minAmount: 100.00,
      validUntil: '2026-02-23T23:59:59Z',
      claimed: false
    },
    {
      id: '2',
      name: '限时特惠券',
      description: '满50减5元',
      discount: 5.00,
      minAmount: 50.00,
      validUntil: '2026-01-30T23:59:59Z',
      claimed: false
    }
  ],
  stats: {
    totalClicks: 1250,
    totalConversions: 89,
    totalEarnings: 1256.78,
    todayEarnings: 45.50,
    inviteCount: 15,
    teamMembers: {
      level1: 8,
      level2: 12,
      level3: 6
    }
  },
  shortLinks: [
    {
      id: '1',
      shortCode: 'abc123',
      originalUrl: 'https://example.com/landing',
      totalClicks: 125,
      conversionRate: 7.2,
      createdAt: '2026-01-20T10:00:00Z'
    }
  ]
};

// Test wrapper
const createTestWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

  return ({ children }) => (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>
        <AuthProvider>
          <NotificationProvider>
            {children}
          </NotificationProvider>
        </AuthProvider>
      </BrowserRouter>
    </QueryClientProvider>
  );
};

// Mock fetch
global.fetch = jest.fn();
global.URLSearchParams = jest.fn();

describe('用户操作前端测试套件', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = createTestWrapper();
    fetch.mockClear();
    localStorage.clear();
  });

  describe('优惠券功能测试', () => {
    test('应该正确显示优惠券列表', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.coupons })
      });

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('新用户专享优惠券')).toBeInTheDocument();
        expect(screen.getByText('限时特惠券')).toBeInTheDocument();
        expect(screen.getByText('满100减10元')).toBeInTheDocument();
        expect(screen.getByText('满50减5元')).toBeInTheDocument();
      });
    });

    test('应该能够领取优惠券', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.coupons })
      });

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, message: '优惠券领取成功' })
      });

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('立即领取')).toBeInTheDocument();
      });

      const claimButton = screen.getByText('立即领取');
      fireEvent.click(claimButton);

      await waitFor(() => {
        expect(screen.getByText('优惠券领取成功')).toBeInTheDocument();
      });
    });

    test('应该显示已领取状态', async () => {
      const claimedCoupons = mockResponses.coupons.map(c => ({ ...c, claimed: true }));
      
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: claimedCoupons })
      });

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('已领取')).toBeInTheDocument();
        expect(screen.getByText('立即领取')).not.toBeInTheDocument();
      });
    });
  });

  describe('统计数据显示测试', () => {
    test('应该正确显示个人统计数据', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.stats })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('1,250')).toBeInTheDocument(); // totalClicks
        expect(screen.getByText('89')).toBeInTheDocument(); // totalConversions
        expect(screen.getByText('¥1,256.78')).toBeInTheDocument(); // totalEarnings
        expect(screen.getByText('¥45.50')).toBeInTheDocument(); // todayEarnings
      });
    });

    test('应该显示团队统计数据', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: {
            level1Count: 8,
            level2Count: 12,
            level3Count: 6,
            totalTeamEarnings: 3456.78
          }
        })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('8')).toBeInTheDocument();
        expect(screen.getByText('12')).toBeInTheDocument();
        expect(screen.getByText('6')).toBeInTheDocument();
        expect(screen.getByText('¥3,456.78')).toBeInTheDocument();
      });
    });

    test('应该显示趋势图表', async () => {
      const trendData = {
        dailyStats: [
          { date: '2026-01-20', clicks: 100, conversions: 8 },
          { date: '2026-01-21', clicks: 120, conversions: 10 },
          { date: '2026-01-22', clicks: 110, conversions: 9 }
        ]
      };

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: trendData })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        // 验证图表渲染（这里简化为验证数据点存在）
        expect(screen.getByTestId('trend-chart')).toBeInTheDocument();
      });
    });
  });

  describe('邀请功能测试', () => {
    test('应该生成邀请链接', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: { 
            inviteCode: 'INVITE123',
            inviteLink: 'https://mosquito.com/invite/INVITE123'
          }
        })
      });

      render(<InviteModal />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('INVITE123')).toBeInTheDocument();
        expect(screen.getByText('https://mosquito.com/invite/INVITE123')).toBeInTheDocument();
      });
    });

    test('应该能够复制邀请链接', async () => {
      // Mock clipboard API
      Object.assign(navigator, {
        clipboard: {
          writeText: jest.fn().mockResolvedValue(),
        },
      });

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: { 
            inviteCode: 'INVITE123',
            inviteLink: 'https://mosquito.com/invite/INVITE123'
          }
        })
      });

      render(<InviteModal />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('复制链接')).toBeInTheDocument();
      });

      const copyButton = screen.getByText('复制链接');
      fireEvent.click(copyButton);

      await waitFor(() => {
        expect(navigator.clipboard.writeText).toHaveBeenCalledWith('https://mosquito.com/invite/INVITE123');
        expect(screen.getByText('链接已复制')).toBeInTheDocument();
      });
    });

    test('应该显示邀请记录', async () => {
      const inviteRecords = [
        {
          id: '1',
          inviteePhone: '138****8001',
          level: 1,
          reward: 10.00,
          createdAt: '2026-01-20T10:00:00Z'
        }
      ];

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: inviteRecords })
      });

      render(<InviteModal />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('138****8001')).toBeInTheDocument();
        expect(screen.getByText('10.00')).toBeInTheDocument();
      });
    });
  });

  describe('短链功能测试', () => {
    test('应该生成短链', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: { 
            id: '1',
            shortCode: 'abc123',
            shortUrl: 'https://mosquito.com/s/abc123',
            originalUrl: 'https://example.com/landing'
          }
        })
      });

      render(<UserDashboard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('生成短链')).toBeInTheDocument();
      });

      const generateButton = screen.getByText('生成短链');
      fireEvent.click(generateButton);

      await waitFor(() => {
        expect(screen.getByText('abc123')).toBeInTheDocument();
        expect(screen.getByText('https://mosquito.com/s/abc123')).toBeInTheDocument();
      });
    });

    test('应该显示短链统计', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.shortLinks })
      });

      render(<UserDashboard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('125')).toBeInTheDocument(); // totalClicks
        expect(screen.getByText('7.2%')).toBeInTheDocument(); // conversionRate
      });
    });
  });

  describe('用户交互流程测试', () => {
    test('完整的用户注册到使用流程', async () => {
      // Mock 注册API
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: { 
            token: 'mock-token',
            user: { id: '1', phone: '13800138001' }
          }
        })
      });

      // Mock 用户信息API
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ 
          success: true, 
          data: { 
            id: '1',
            phone: '13800138001',
            createdAt: '2026-01-20T10:00:00Z'
          }
        })
      });

      // Mock 优惠券API
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.coupons })
      });

      render(<UserDashboard />, { wrapper });

      // 模拟用户登录
      act(() => {
        localStorage.setItem('token', 'mock-token');
      });

      await waitFor(() => {
        expect(screen.getByText('新用户专享优惠券')).toBeInTheDocument();
      });

      // 领取优惠券
      const claimButton = screen.getByText('立即领取');
      fireEvent.click(claimButton);

      await waitFor(() => {
        expect(screen.getByText('优惠券领取成功')).toBeInTheDocument();
      });
    });

    test('应该处理网络错误', async () => {
      fetch.mockRejectedValueOnce(new Error('Network error'));

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('网络错误，请稍后重试')).toBeInTheDocument();
      });
    });

    test('应该处理API错误响应', async () => {
      fetch.mockResolvedValueOnce({
        ok: false,
        status: 400,
        json: async () => ({ success: false, message: '请求参数错误' })
      });

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('请求参数错误')).toBeInTheDocument();
      });
    });
  });

  describe('响应式设计测试', () => {
    test('应该在移动设备上正确显示', async () => {
      // Mock mobile viewport
      Object.defineProperty(window, 'innerWidth', {
        writable: true,
        configurable: true,
        value: 375,
      });

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.stats })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByTestId('mobile-stats-container')).toBeInTheDocument();
        expect(screen.getByText('1,250')).toBeInTheDocument();
      });
    });

    test('应该在桌面设备上正确显示', async () => {
      // Mock desktop viewport
      Object.defineProperty(window, 'innerWidth', {
        writable: true,
        configurable: true,
        value: 1200,
      });

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.stats })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByTestId('desktop-stats-container')).toBeInTheDocument();
        expect(screen.getByText('1,250')).toBeInTheDocument();
      });
    });
  });

  describe('性能测试', () => {
    test('应该在大数据量下保持响应', async () => {
      // 生成大量优惠券数据
      const largeCoupons = Array.from({ length: 1000 }, (_, i) => ({
        id: i.toString(),
        name: `优惠券 ${i + 1}`,
        description: `满${(i + 1) * 10}减${i + 1}元`,
        discount: i + 1,
        minAmount: (i + 1) * 10,
        claimed: false
      }));

      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: largeCoupons })
      });

      const startTime = performance.now();
      render(<CouponCard />, { wrapper });
      
      await waitFor(() => {
        expect(screen.getByText('优惠券 1')).toBeInTheDocument();
      });

      const renderTime = performance.now() - startTime;
      expect(renderTime).toBeLessThan(1000); // 渲染时间应小于1秒
    });
  });

  describe('可访问性测试', () => {
    test('应该支持键盘导航', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.coupons })
      });

      render(<CouponCard />, { wrapper });

      await waitFor(() => {
        expect(screen.getByText('立即领取')).toBeInTheDocument();
      });

      const claimButton = screen.getByText('立即领取');
      
      // 测试Tab键导航
      claimButton.focus();
      expect(claimButton).toHaveFocus();

      // 测试Enter键触发
      fireEvent.keyPress(claimButton, { key: 'Enter', code: 'Enter' });

      await waitFor(() => {
        expect(screen.getByText('优惠券领取成功')).toBeInTheDocument();
      });
    });

    test('应该提供正确的ARIA标签', async () => {
      fetch.mockResolvedValueOnce({
        ok: true,
        json: async () => ({ success: true, data: mockResponses.stats })
      });

      render(<StatsCard />, { wrapper });

      await waitFor(() => {
        const statsContainer = screen.getByTestId('stats-container');
        expect(statsContainer).toHaveAttribute('aria-label', '用户统计数据');
      });
    });
  });
});

// 集成测试：用户完整操作流程
describe('用户完整操作流程集成测试', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = createTestWrapper();
    fetch.mockClear();
  });

  test('从注册到查看数据的完整流程', async () => {
    // 1. 用户注册
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ 
        success: true, 
        data: { 
          token: 'user-token',
          user: { id: '1', phone: '13800138001' }
        }
      })
    });

    // 2. 获取用户信息
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ 
        success: true, 
        data: { 
          id: '1',
          phone: '13800138001',
          isNewUser: true
        }
      })
    });

    // 3. 获取优惠券列表
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ success: true, data: mockResponses.coupons })
    });

    // 4. 领取优惠券
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ success: true, message: '领取成功' })
    });

    // 5. 获取统计数据
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ success: true, data: mockResponses.stats })
    });

    // 6. 生成邀请码
    fetch.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ 
        success: true, 
        data: { 
          inviteCode: 'INVITE123',
          inviteLink: 'https://mosquito.com/invite/INVITE123'
        }
      })
    });

    render(<UserDashboard />, { wrapper });

    // 验证完整流程
    await waitFor(() => {
      expect(screen.getByText('新用户专享优惠券')).toBeInTheDocument();
    });

    // 领取优惠券
    const claimButton = screen.getByText('立即领取');
    fireEvent.click(claimButton);

    await waitFor(() => {
      expect(screen.getByText('领取成功')).toBeInTheDocument();
    });

    // 查看统计数据
    await waitFor(() => {
      expect(screen.getByText('1,250')).toBeInTheDocument();
      expect(screen.getByText('89')).toBeInTheDocument();
    });

    // 生成邀请码
    await waitFor(() => {
      expect(screen.getByText('INVITE123')).toBeInTheDocument();
    });
  });
});