import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import Taro from '@tarojs/taro'
import CartPage from '@/pages/cart/index'

// Mock Taro相关API
jest.mock('@tarojs/taro', () => ({
  default: {
    navigateBack: jest.fn(),
    navigateTo: jest.fn(),
    showToast: jest.fn(),
    showModal: jest.fn(() => Promise.resolve({ confirm: true })),
    getStorageSync: jest.fn(),
    setStorageSync: jest.fn(),
    removeStorageSync: jest.fn(),
  },
}))

// Mock购物车hook
jest.mock('@/contexts/CartContext', () => ({
  useCart: () => ({
    cart: {
      items: [
        {
          id: 1,
          name: '测试商品1',
          price: 29.9,
          image: 'test-image1.jpg',
          stock: 10,
          quantity: 2,
          spec: '红色/M',
        },
        {
          id: 2,
          name: '测试商品2',
          price: 49.9,
          image: 'test-image2.jpg',
          stock: 5,
          quantity: 1,
          spec: '蓝色/L',
        },
      ],
      totalAmount: 109.7,
      totalCount: 3,
    },
    updateQuantity: jest.fn(),
    removeFromCart: jest.fn(),
    clearCart: jest.fn(),
    isLoading: false,
  }),
}))

// Mock布局组件
jest.mock('@/layouts/tab-bar-layout', () => ({
  TabBarLayout: ({ children }: any) => <div>{children}</div>,
}))

// Mock导航栏组件
jest.mock('@/components/ui/navbar', () => ({
  Navbar: ({ title, onClickRight }: any) => (
    <div>
      <div>{title}</div>
      <button onClick={onClickRight}>清空购物车</button>
    </div>
  ),
}))

// Mock按钮组件
jest.mock('@/components/ui/button', () => ({
  Button: ({ children, onClick, disabled, className }: any) => (
    <button onClick={onClick} disabled={disabled} className={className}>
      {children}
    </button>
  ),
}))

// Mock图片组件
jest.mock('@/components/ui/image', () => ({
  Image: ({ src, className, mode }: any) => (
    <img src={src} className={className} alt="商品图片" />
  ),
}))

describe('购物车页面', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  it('应该正确渲染购物车页面标题', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('购物车')).toBeDefined()
  })

  it('应该显示购物车中的商品列表', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('测试商品1')).toBeDefined()
    expect(getByText('测试商品2')).toBeDefined()
    expect(getByText('¥29.90')).toBeDefined()
    expect(getByText('¥49.90')).toBeDefined()
  })

  it('应该显示商品规格信息', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('红色/M')).toBeDefined()
    expect(getByText('蓝色/L')).toBeDefined()
  })

  it('应该显示商品数量选择器', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('2')).toBeDefined() // 商品1的数量
    expect(getByText('1')).toBeDefined() // 商品2的数量
  })

  it('应该显示底部结算栏', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('全选')).toBeDefined()
    expect(getByText('总计')).toBeDefined()
    expect(getByText('去结算(0)')).toBeDefined()
  })

  it('应该支持全选功能', () => {
    const { getByText } = render(<CartPage />)
    const selectAllButton = getByText('全选')

    fireEvent.click(selectAllButton)

    // 检查结算按钮文本变化
    expect(getByText('去结算(2)')).toBeDefined()
  })

  it('应该支持单个商品选择', () => {
    const { getByText } = render(<CartPage />)
    const selectAllButton = getByText('全选')

    fireEvent.click(selectAllButton)

    // 再次点击取消全选
    fireEvent.click(selectAllButton)
    expect(getByText('去结算(0)')).toBeDefined()
  })

  it('应该显示清空购物车按钮', () => {
    const { getByText } = render(<CartPage />)
    const clearButton = getByText('清空购物车')

    fireEvent.click(clearButton)

    expect(Taro.showModal).toHaveBeenCalledWith({
      title: '清空购物车',
      content: '确定要清空购物车吗？',
      success: expect.any(Function),
    })
  })

  it('应该显示删除按钮', () => {
    const { getAllByText } = render(<CartPage />)
    const deleteButtons = getAllByText('删除')

    expect(deleteButtons).toHaveLength(2)

    fireEvent.click(deleteButtons[0])

    expect(Taro.showModal).toHaveBeenCalledWith({
      title: '删除商品',
      content: '确定要删除这个商品吗？',
      success: expect.any(Function),
    })
  })

  it('应该显示库存不足提示', () => {
    const { getByText } = render(<CartPage />)
    expect(getByText('仅剩5件')).toBeDefined() // 商品2的库存
  })

  it('应该显示广告区域', () => {
    const { container } = render(<CartPage />)
    const adElement = container.querySelector('.cart-advertisement')
    expect(adElement).toBeDefined()
  })

  describe('空购物车状态', () => {
    beforeEach(() => {
      // Mock空购物车状态
      jest.doMock('@/utils/cart', () => ({
        useCart: () => ({
          cart: {
            items: [],
            totalAmount: 0,
            totalCount: 0,
          },
          updateQuantity: jest.fn(),
          removeFromCart: jest.fn(),
          clearCart: jest.fn(),
          isLoading: false,
        }),
      }))
    })

    it('应该显示空购物车状态', () => {
      const { getByText } = render(<CartPage />)
      expect(getByText('购物车是空的')).toBeDefined()
      expect(getByText('去首页逛逛')).toBeDefined()
    })

    it('应该隐藏底部结算栏', () => {
      const { queryByText } = render(<CartPage />)
      expect(queryByText('去结算')).toBeNull()
    })
  })

  describe('结算功能', () => {
    it('应该阻止未选择商品时结算', () => {
      const { getByText } = render(<CartPage />)
      const checkoutButton = getByText('去结算(0)')

      fireEvent.click(checkoutButton)

      expect(Taro.showToast).toHaveBeenCalledWith({
        title: '请选择商品',
        icon: 'none',
      })
    })

    it('应该允许选择商品后结算', () => {
      const { getByText } = render(<CartPage />)
      const selectAllButton = getByText('全选')
      const checkoutButton = getByText('去结算(0)')

      fireEvent.click(selectAllButton)
      fireEvent.click(checkoutButton)

      expect(Taro.setStorageSync).toHaveBeenCalledWith('checkoutItems', {
        items: expect.any(Array),
        totalAmount: expect.any(Number),
      })
      expect(Taro.navigateTo).toHaveBeenCalledWith({
        url: '/pages/order-submit/index',
      })
    })
  })
})