import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import GoodsCard, { GoodsData } from '@/components/goods-card'
import { GoodsSpecSelector } from '@/components/goods-spec-selector'
import { goodsClient } from '@/api'

// Mock API客户端
jest.mock('@/api', () => ({
  goodsClient: {
    ':id': {
      children: {
        $get: jest.fn()
      }
    }
  }
}))

// Mock Taro组件
jest.mock('@tarojs/components', () => ({
  View: ({ children, className, onClick, id }: any) => (
    <div className={className} onClick={onClick} id={id}>
      {children}
    </div>
  ),
  Image: ({ src, className, mode, lazyLoad }: any) => (
    <img src={src} className={className} data-mode={mode} data-lazyload={lazyLoad} alt="" />
  ),
  Text: ({ children, className }: any) => (
    <span className={className}>{children}</span>
  ),
  ScrollView: ({ children, className, scrollY }: any) => (
    <div className={className} data-scroll-y={scrollY}>
      {children}
    </div>
  )
}))

// Mock TDesignIcon组件
jest.mock('@/components/tdesign/icon', () => ({
  __esModule: true,
  default: ({ name, size, color, onClick }: any) => (
    <div
      data-testid="tdesign-icon"
      data-name={name}
      data-size={size}
      data-color={color}
      onClick={onClick}
    >
      {name}图标
    </div>
  )
}))

// Mock UI Button组件
jest.mock('@/components/ui/button', () => ({
  Button: ({ children, onClick, className, disabled, size, variant }: any) => (
    <button
      className={className}
      onClick={onClick}
      disabled={disabled}
      data-size={size}
      data-variant={variant}
    >
      {children}
    </button>
  )
}))


describe('GoodsCard组件', () => {
  const mockOnClick = jest.fn()
  const mockOnAddCart = jest.fn()

  beforeEach(() => {
    jest.clearAllMocks()

    // 设置默认的API模拟响应
    const mockResponse = {
      status: 200,
      json: async () => ({
        data: [
          {
            id: 101,
            name: '红色款',
            price: 299,
            stock: 50,
            imageFile: null
          }
        ],
        total: 1,
        page: 1,
        pageSize: 100,
        totalPages: 1
      })
    }
    ;(goodsClient[':id'].children.$get as jest.Mock).mockResolvedValue(mockResponse)
  })

  // 测试单规格商品直接添加到购物车场景
  it('单规格商品直接添加到购物车', () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '测试商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      originPrice: 399,
      tags: ['热销'],
      hasSpecOptions: false,
      parentGoodsId: undefined,
      quantity: 1
    }

    render(
      <GoodsCard
        data={goodsData}
        onClick={mockOnClick}
        onAddCart={mockOnAddCart}
      />
    )

    // 验证商品信息显示
    expect(screen.getByText('测试商品')).toBeInTheDocument()
    expect(screen.getByAltText('')).toHaveAttribute('src', 'http://example.com/image.jpg')
    expect(screen.getByText('299.00')).toBeInTheDocument()

    // 点击购物车按钮
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 验证直接调用onAddCart，不显示规格选择器
    expect(mockOnAddCart).toHaveBeenCalledWith(goodsData)
    expect(screen.queryByText('选择规格')).not.toBeInTheDocument()
  })

  // 测试多规格商品弹出规格选择器场景
  it('多规格商品弹出规格选择器', async () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '多规格商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      originPrice: 399,
      hasSpecOptions: true,
      parentGoodsId: 1, // 父商品ID
      quantity: 1
    }

    render(
      <GoodsCard
        data={goodsData}
        onClick={mockOnClick}
        onAddCart={mockOnAddCart}
      />
    )

    // 初始不显示规格选择器
    expect(screen.queryByText('选择规格')).not.toBeInTheDocument()

    // 点击购物车按钮
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 验证显示规格选择器（等待加载完成）
    await waitFor(() => {
      expect(screen.getByText('选择规格')).toBeInTheDocument()
    })

    // 验证规格选项加载
    await waitFor(() => {
      expect(screen.getByText('红色款')).toBeInTheDocument()
    })

    // 验证未调用onAddCart
    expect(mockOnAddCart).not.toHaveBeenCalled()
  })

  // 测试规格选择后成功添加到购物车场景
  it('规格选择后成功添加到购物车', async () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '多规格商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: true,
      parentGoodsId: 1,
      quantity: 1
    }

    render(
      <GoodsCard
        data={goodsData}
        onClick={mockOnClick}
        onAddCart={mockOnAddCart}
      />
    )

    // 点击购物车按钮弹出规格选择器
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 等待规格选择器加载
    await waitFor(() => {
      expect(screen.getByText('选择规格')).toBeInTheDocument()
    })

    // 等待规格选项加载
    await waitFor(() => {
      expect(screen.getByText('红色款')).toBeInTheDocument()
    })

    // 点击规格选项
    fireEvent.click(screen.getByText('红色款'))

    // 等待确认按钮出现（规格选中后应该出现）
    await waitFor(() => {
      expect(screen.getByText(/加入购物车/)).toBeInTheDocument()
    })

    // 点击确认按钮
    const confirmButton = screen.getByText(/加入购物车/)
    fireEvent.click(confirmButton)

    // 验证onAddCart被调用，且包含规格信息
    expect(mockOnAddCart).toHaveBeenCalledWith({
      id: '101', // 规格ID转换为字符串
      name: '红色款', // 规格名称
      cover_image: 'http://example.com/image.jpg',
      price: 299, // 规格价格
      hasSpecOptions: true,
      parentGoodsId: 1, // 父商品ID保持不变
      quantity: 1, // 数量
      stock: 50, // 库存
      image: 'http://example.com/image.jpg' // 图片
    })
  })

  // 测试父子商品关系正确记录场景
  it('父子商品关系正确记录', async () => {
    // 测试父商品
    const parentGoodsData: GoodsData = {
      id: '1',
      name: '父商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: true,
      parentGoodsId: 1, // 父商品的parentGoodsId是自己的ID
      quantity: 1
    }

    const { rerender } = render(
      <GoodsCard
        data={parentGoodsData}
        onAddCart={mockOnAddCart}
      />
    )

    // 点击购物车按钮
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 等待规格选择器显示（验证父商品弹出规格选择器）
    await waitFor(() => {
      expect(screen.getByText('选择规格')).toBeInTheDocument()
    })

    // 测试子商品
    const childGoodsData: GoodsData = {
      id: '101',
      name: '子商品规格',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: false, // 子商品没有规格选项
      parentGoodsId: 1, // 指向父商品
      quantity: 1
    }

    rerender(
      <GoodsCard
        data={childGoodsData}
        onAddCart={mockOnAddCart}
      />
    )

    // 子商品直接添加到购物车
    fireEvent.click(screen.getByTestId('tdesign-icon'))
    expect(mockOnAddCart).toHaveBeenCalledWith(childGoodsData)
  })

  // 测试商品卡片在不同页面的数据传递正确性
  it('处理无规格选项但有parentGoodsId的情况', () => {
    const goodsData: GoodsData = {
      id: '101',
      name: '子商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: false, // 明确无规格选项
      parentGoodsId: 1, // 但有父商品ID
      quantity: 1
    }

    render(
      <GoodsCard
        data={goodsData}
        onAddCart={mockOnAddCart}
      />
    )

    // 点击购物车按钮
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 应该直接添加到购物车，不显示规格选择器
    expect(mockOnAddCart).toHaveBeenCalledWith(goodsData)
    expect(screen.queryByText('选择规格')).not.toBeInTheDocument()
  })

  // 测试商品卡片点击事件
  it('点击商品卡片触发onClick回调', () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '测试商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299
    }

    render(
      <GoodsCard
        data={goodsData}
        onClick={mockOnClick}
      />
    )

    // 点击商品卡片
    const goodsCard = screen.getByText('测试商品').closest('div')
    fireEvent.click(goodsCard!)

    expect(mockOnClick).toHaveBeenCalledWith(goodsData)
  })

  // 测试规格选择器关闭功能
  it('关闭规格选择器', async () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '多规格商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: true,
      parentGoodsId: 1,
      quantity: 1
    }

    const { container } = render(
      <GoodsCard
        data={goodsData}
        onAddCart={mockOnAddCart}
      />
    )

    // 点击购物车按钮弹出规格选择器
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 等待规格选择器显示
    await waitFor(() => {
      expect(screen.getByText('选择规格')).toBeInTheDocument()
    })

    // 点击关闭按钮
    const closeButton = container.querySelector('.spec-modal-close')
    expect(closeButton).not.toBeNull()
    fireEvent.click(closeButton!)

    // 验证规格选择器消失
    await waitFor(() => {
      expect(screen.queryByText('选择规格')).not.toBeInTheDocument()
    })
  })

  // 测试货币符号显示
  it('显示自定义货币符号', () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '测试商品',
      price: 299
    }

    render(
      <GoodsCard
        data={goodsData}
        currency="$"
      />
    )

    // 验证货币符号显示
    expect(screen.getByText('$')).toBeInTheDocument()
    expect(screen.getByText('299.00')).toBeInTheDocument()
  })

  // 测试无价格商品
  it('处理无价格商品', () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '无价格商品'
    }

    render(
      <GoodsCard
        data={goodsData}
      />
    )

    // 验证商品名称显示
    expect(screen.getByText('无价格商品')).toBeInTheDocument()
    // 价格区域不应该显示
    expect(screen.queryByText('¥')).not.toBeInTheDocument()
  })

  // 测试ID类型安全转换 - 修复006.021 bug
  it('正确处理规格ID类型转换，确保购物车添加成功', async () => {
    const goodsData: GoodsData = {
      id: '1',
      name: '多规格商品',
      cover_image: 'http://example.com/image.jpg',
      price: 299,
      hasSpecOptions: true,
      parentGoodsId: 1,
      quantity: 1
    }

    render(
      <GoodsCard
        data={goodsData}
        onAddCart={mockOnAddCart}
      />
    )

    // 点击购物车按钮弹出规格选择器
    const cartButton = screen.getByTestId('tdesign-icon')
    fireEvent.click(cartButton)

    // 等待规格选择器加载
    await waitFor(() => {
      expect(screen.getByText('选择规格')).toBeInTheDocument()
    })

    // 等待规格选项加载
    await waitFor(() => {
      expect(screen.getByText('红色款')).toBeInTheDocument()
    })

    // 点击规格选项
    fireEvent.click(screen.getByText('红色款'))

    // 等待确认按钮出现
    await waitFor(() => {
      expect(screen.getByText(/加入购物车/)).toBeInTheDocument()
    })

    // 点击确认按钮
    const confirmButton = screen.getByText(/加入购物车/)
    fireEvent.click(confirmButton)

    // 验证onAddCart被调用，且ID正确转换为字符串
    expect(mockOnAddCart).toHaveBeenCalledWith(
      expect.objectContaining({
        id: '101', // 规格ID必须转换为字符串
        name: '红色款',
        parentGoodsId: 1,
        price: 299,
        quantity: 1,
        stock: 50
      })
    )

    // 验证ID是字符串类型（通过expect.any(String)）
    expect(mockOnAddCart).toHaveBeenCalledWith(
      expect.objectContaining({
        id: expect.any(String) // 确保ID是字符串类型
      })
    )
  })
})