import React from 'react'
import { render } from '@testing-library/react'
import { CartProvider, useCart, CartItem } from '@/contexts/CartContext'
import { mockShowToast, mockGetStorageSync, mockSetStorageSync } from '~/__mocks__/taroMock'

// Mock Taro API
jest.mock('@tarojs/taro', () => jest.requireActual('~/__mocks__/taroMock'))

// 测试组件用于访问购物车hook
const TestComponent = ({ action, item }: { action: string; item?: CartItem }) => {
  const cart = useCart()

  React.useEffect(() => {
    console.log('TestComponent useEffect called, action:', action, 'item:', item, 'isLoading:', cart.isLoading)
    // 等待购物车加载完成后再添加商品
    if (!cart.isLoading && action === 'add' && item) {
      console.log('Calling addToCart with item:', item)
      cart.addToCart(item)
    }
  }, [action, item, cart.isLoading])

  console.log('TestComponent rendering, cart items:', cart.cart.items, 'isLoading:', cart.isLoading)

  return (
    <div>
      <div data-testid="items-count">{cart.cart.items.length}</div>
      <div data-testid="total-count">{cart.cart.totalCount}</div>
      <div data-testid="total-amount">{cart.cart.totalAmount}</div>
      {cart.cart.items.map((item, index) => (
        <div key={index} data-testid={`item-${index}`}>
          <span data-testid={`item-${index}-id`}>{item.id}</span>
          <span data-testid={`item-${index}-name`}>{item.name}</span>
          {/* spec字段已移除 */}
          <span data-testid={`item-${index}-quantity`}>{item.quantity}</span>
          <span data-testid={`item-${index}-stock`} style={{ display: 'none' }}>{item.stock}</span>
        </div>
      ))}
    </div>
  )
}

describe('CartContext - 规格支持', () => {
  beforeEach(() => {
    mockGetStorageSync.mockReturnValue(null)
    mockSetStorageSync.mockClear()
    mockShowToast.mockClear()
  })

  it('应该支持添加父商品到购物车', () => {
    const parentGoods: CartItem = {
      id: 1001,
      parentGoodsId: 0, // 父商品，无父商品
      name: '测试父商品',
      price: 99.9,
      image: 'parent.jpg',
      stock: 10,
      quantity: 2,
    }

    const { getByTestId } = render(
      <CartProvider>
        <TestComponent action="add" item={parentGoods} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('1')
    expect(getByTestId('item-0-id').textContent).toBe('1001')
    expect(getByTestId('item-0-name').textContent).toBe('测试父商品')
    expect(mockSetStorageSync).toHaveBeenCalled()
  })

  it('应该支持添加子商品（带规格）到购物车', () => {
    const childGoods: CartItem = {
      id: 2001, // 子商品ID
      parentGoodsId: 2000, // 父商品ID
      name: '红色/M', // 规格名称
      price: 109.9,
      image: 'child.jpg',
      stock: 5,
      quantity: 1,
    }

    const { getByTestId } = render(
      <CartProvider>
        <TestComponent action="add" item={childGoods} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('1')
    expect(getByTestId('item-0-id').textContent).toBe('2001')
    expect(getByTestId('item-0-name').textContent).toBe('红色/M')
    expect(mockSetStorageSync).toHaveBeenCalled()
  })

  it('应该支持添加同一子商品多次（数量累加）', () => {
    const childGoods1: CartItem = {
      id: 3001,
      parentGoodsId: 3000, // 父商品ID
      name: '蓝色/L', // 规格名称
      price: 89.9,
      image: 'goods.jpg',
      stock: 10,
      quantity: 1,
    }

    const childGoods2: CartItem = {
      id: 3001, // 同一子商品ID
      parentGoodsId: 3000, // 父商品ID
      name: '蓝色/L', // 规格名称
      price: 89.9,
      image: 'goods.jpg',
      stock: 10,
      quantity: 3,
    }

    const { getByTestId, rerender } = render(
      <CartProvider>
        <TestComponent action="add" item={childGoods1} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('1')
    console.log('Item 0 id:', getByTestId('item-0-id').textContent)
    console.log('Item 0 name:', getByTestId('item-0-name').textContent)
    const quantityElement = getByTestId('item-0-quantity')
    console.log('Quantity element text:', quantityElement.textContent)
    // 修复：检查数量是否正确，应该是1而不是库存值10
    expect(parseInt(quantityElement.textContent || '0')).toBe(1)

    // 重新渲染添加更多数量
    rerender(
      <CartProvider>
        <TestComponent action="add" item={childGoods2} />
      </CartProvider>
    )

    expect(getByTestId('item-0-quantity').textContent).toBe('4') // 1 + 3
  })

  it('应该限制数量不超过库存', () => {
    const childGoods: CartItem = {
      id: 4001,
      parentGoodsId: 4000, // 父商品ID
      name: '测试商品 - 黑色/XL',
      price: 129.9,
      image: 'goods.jpg',
      stock: 2, // 库存只有2
      quantity: 3, // 尝试购买3个
    }

    const { getByTestId } = render(
      <CartProvider>
        <TestComponent action="add" item={childGoods} />
      </CartProvider>
    )

    // 应该显示库存不足提示
    expect(mockShowToast).toHaveBeenCalledWith(
      expect.objectContaining({ title: '库存不足' })
    )
    // 商品不应被添加
    expect(getByTestId('items-count').textContent).toBe('0')
  })

  it('应该支持同时添加父商品和不同子商品', () => {
    const parentGoods: CartItem = {
      id: 5001,
      parentGoodsId: 0, // 父商品，无父商品
      name: '测试父商品',
      price: 199.9,
      image: 'parent.jpg',
      stock: 20,
      quantity: 1,
    }

    const childGoods1: CartItem = {
      id: 5002, // 子商品ID1
      parentGoodsId: 5001, // 父商品ID
      name: '测试父商品 - 规格A',
      price: 219.9,
      image: 'child1.jpg',
      stock: 5,
      quantity: 2,
    }

    const childGoods2: CartItem = {
      id: 5003, // 子商品ID2
      parentGoodsId: 5001, // 父商品ID
      name: '测试父商品 - 规格B',
      price: 229.9,
      image: 'child2.jpg',
      stock: 3,
      quantity: 1,
    }

    const { getByTestId, rerender } = render(
      <CartProvider>
        <TestComponent action="add" item={parentGoods} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('1')

    // 添加第一个子商品
    rerender(
      <CartProvider>
        <TestComponent action="add" item={childGoods1} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('2')

    // 添加第二个子商品
    rerender(
      <CartProvider>
        <TestComponent action="add" item={childGoods2} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('3')
    expect(getByTestId('item-0-id').textContent).toBe('5001')
    expect(getByTestId('item-1-id').textContent).toBe('5002')
    expect(getByTestId('item-2-id').textContent).toBe('5003')
  })

  it('应该支持切换购物车项规格', () => {
    // 首先添加一个子商品到购物车
    const childGoods: CartItem = {
      id: 6001,
      parentGoodsId: 6000, // 父商品ID
      name: '测试父商品 - 规格A',
      price: 99.9,
      image: 'child1.jpg',
      stock: 10,
      quantity: 2,
    }

    // 创建一个新的测试组件来测试switchSpec
    const TestSwitchSpecComponent = ({ cartItemId, newChildGoods }: {
      cartItemId?: number,
      newChildGoods?: { id: number; name: string; price: number; stock: number; image?: string }
    }) => {
      const cart = useCart()

      React.useEffect(() => {
        if (!cart.isLoading && cartItemId && newChildGoods) {
          cart.switchSpec(cartItemId, newChildGoods)
        }
      }, [cart.isLoading, cartItemId, newChildGoods])

      return (
        <div>
          <div data-testid="items-count">{cart.cart.items.length}</div>
          {cart.cart.items.map((item, index) => (
            <div key={index} data-testid={`item-${index}`}>
              <span data-testid={`item-${index}-id`}>{item.id}</span>
              <span data-testid={`item-${index}-name`}>{item.name}</span>
              {/* spec字段已移除 */}
              <span data-testid={`item-${index}-quantity`}>{item.quantity}</span>
              <span data-testid={`item-${index}-price`}>{item.price}</span>
            </div>
          ))}
        </div>
      )
    }

    const { getByTestId, rerender } = render(
      <CartProvider>
        <TestComponent action="add" item={childGoods} />
      </CartProvider>
    )

    expect(getByTestId('items-count').textContent).toBe('1')
    expect(getByTestId('item-0-id').textContent).toBe('6001')
    expect(getByTestId('item-0-name').textContent).toBe('测试父商品 - 规格A')

    // 切换到新规格
    const newChildGoods = {
      id: 6002,
      name: '规格B', // 规格名称
      price: 119.9,
      stock: 5,
      image: 'child2.jpg',
    }

    rerender(
      <CartProvider>
        <TestSwitchSpecComponent cartItemId={6001} newChildGoods={newChildGoods} />
      </CartProvider>
    )

    // 验证规格已切换
    expect(getByTestId('items-count').textContent).toBe('1')
    expect(getByTestId('item-0-id').textContent).toBe('6002') // ID已更新
    expect(getByTestId('item-0-name').textContent).toBe('规格B') // 规格名称
    expect(getByTestId('item-0-price').textContent).toBe('119.9')
    expect(getByTestId('item-0-quantity').textContent).toBe('2') // 数量保持不变
  })

  it('切换规格时应该验证库存', () => {
    const childGoods: CartItem = {
      id: 7001,
      parentGoodsId: 7000,
      name: '测试商品 - 规格A',
      price: 50,
      image: 'test.jpg',
      stock: 10,
      quantity: 8, // 当前数量8
    }

    const TestSwitchSpecComponent = ({ cartItemId, newChildGoods }: {
      cartItemId?: number,
      newChildGoods?: { id: number; name: string; price: number; stock: number; image?: string }
    }) => {
      const cart = useCart()

      React.useEffect(() => {
        if (!cart.isLoading && cartItemId && newChildGoods) {
          cart.switchSpec(cartItemId, newChildGoods)
        }
      }, [cart.isLoading, cartItemId, newChildGoods])

      return <div data-testid="toast-called">{mockShowToast.mock.calls.length}</div>
    }

    // 添加商品到购物车
    const { getByTestId, rerender } = render(
      <CartProvider>
        <TestComponent action="add" item={childGoods} />
      </CartProvider>
    )

    // 尝试切换到库存不足的规格（库存只有5，但当前数量是8）
    const newChildGoods = {
      id: 7002,
      name: '测试商品 - 规格B',
      price: 60,
      stock: 5, // 库存不足
      image: 'test2.jpg',
    }

    rerender(
      <CartProvider>
        <TestSwitchSpecComponent cartItemId={7001} newChildGoods={newChildGoods} />
      </CartProvider>
    )

    // 应该显示库存不足提示
    expect(mockShowToast).toHaveBeenCalledWith(
      expect.objectContaining({ title: expect.stringContaining('库存不足') })
    )
  })

  it('单规格商品不应该支持切换规格', () => {
    const singleSpecGoods: CartItem = {
      id: 8001,
      parentGoodsId: 0, // 单规格商品
      name: '单规格商品',
      price: 30,
      image: 'single.jpg',
      stock: 10,
      quantity: 1,
    }

    const TestSwitchSpecComponent = ({ cartItemId, newChildGoods }: {
      cartItemId?: number,
      newChildGoods?: { id: number; name: string; price: number; stock: number; image?: string }
    }) => {
      const cart = useCart()

      React.useEffect(() => {
        if (!cart.isLoading && cartItemId && newChildGoods) {
          cart.switchSpec(cartItemId, newChildGoods)
        }
      }, [cart.isLoading, cartItemId, newChildGoods])

      return <div>Test</div>
    }

    // 添加单规格商品
    const { rerender } = render(
      <CartProvider>
        <TestComponent action="add" item={singleSpecGoods} />
      </CartProvider>
    )

    const newChildGoods = {
      id: 8002,
      name: '新规格',
      price: 40,
      stock: 5,
    }

    rerender(
      <CartProvider>
        <TestSwitchSpecComponent cartItemId={8001} newChildGoods={newChildGoods} />
      </CartProvider>
    )

    // 应该显示不支持切换的提示
    expect(mockShowToast).toHaveBeenCalledWith(
      expect.objectContaining({ title: '该商品不支持切换规格' })
    )
  })
})