import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import SearchResultPage from '@/pages/search-result/index'

// 导入Taro mock函数
import {
  mockNavigateTo,
  mockGetCurrentInstance,
  mockStopPullDownRefresh,
  mockUseRouter
} from '~/__mocks__/taroMock'

// Mock components
jest.mock('@/components/ui/navbar', () => ({
  Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
    <div data-testid="navbar">
      <span>{title}</span>
      <button onClick={onClickLeft}>返回</button>
    </div>
  ),
}))

jest.mock('@/components/goods-list', () => ({
  __esModule: true,
  default: ({
    goodsList,
    onClick,
    onAddCart
  }: {
    goodsList: any[],
    onClick: (goods: any) => void,
    onAddCart: (goods: any) => void
  }) => (
    <div data-testid="goods-list">
      {goodsList.map((goods, index) => (
        <div
          key={goods.id}
          data-testid={`goods-item-${index}`}
          onClick={() => onClick(goods)}
        >
          <span data-testid="goods-name">{goods.name}</span>
          <span data-testid="goods-price">{goods.price}</span>
          <button
            data-testid="add-cart-btn"
            onClick={() => onAddCart(goods)}
          >
            加入购物车
          </button>
        </div>
      ))}
    </div>
  ),
}))

// Mock API client
jest.mock('@/api', () => ({
  goodsClient: {
    $get: jest.fn()
  }
}))

// Mock cart hook
const mockAddToCart = jest.fn()
jest.mock('@/contexts/CartContext', () => ({
  useCart: () => ({
    addToCart: mockAddToCart
  })
}))

describe('SearchResultPage', () => {
  let queryClient: QueryClient

  beforeEach(() => {
    queryClient = new QueryClient({
      defaultOptions: {
        queries: { retry: false },
        mutations: { retry: false },
      },
    })

    // Reset all mocks
    jest.clearAllMocks()
    mockAddToCart.mockClear()

    // Mock Taro.getCurrentInstance
    mockGetCurrentInstance.mockReturnValue({
      router: {
        params: {
          keyword: '手机'
        }
      }
    })

    // Mock Taro.useRouter
    mockUseRouter.mockReturnValue({
      params: {
        keyword: '手机'
      }
    })

    // Mock API response
    const { goodsClient } = require('@/api')
    goodsClient.$get.mockResolvedValue({
      status: 200,
      json: () => Promise.resolve({
        data: [
          {
            id: 1,
            name: 'iPhone 15',
            price: 599900,
            originPrice: 699900,
            stock: 10,
            salesNum: 100,
            imageFile: {
              fullUrl: 'https://example.com/iphone15.jpg'
            }
          },
          {
            id: 2,
            name: 'MacBook Pro',
            price: 1299900,
            originPrice: 1499900,
            stock: 5,
            salesNum: 50,
            imageFile: {
              fullUrl: 'https://example.com/macbook.jpg'
            }
          }
        ],
        pagination: {
          current: 1,
          pageSize: 10,
          total: 2,
          totalPages: 1
        }
      })
    })
  })

  const renderWithProviders = (component: React.ReactElement) => {
    return render(
      <QueryClientProvider client={queryClient}>
        {component}
      </QueryClientProvider>
    )
  }

  it('渲染页面标题和布局', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      expect(screen.getByTestId('navbar')).toBeInTheDocument()
      expect(screen.getByTestId('navbar')).toHaveTextContent('搜索结果')
    })
  })

  it('显示搜索栏和关键词', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      // 验证搜索栏存在
      const searchInput = document.querySelector('.search-input') as HTMLInputElement
      expect(searchInput).toBeInTheDocument()
      expect(searchInput.placeholder).toBe('搜索商品...')
      expect(searchInput.value).toBe('手机')

      // 验证搜索结果标题
      expect(screen.getByText('搜索结果："手机"')).toBeInTheDocument()
      expect(screen.getByText('共找到 2 件商品')).toBeInTheDocument()
    })
  })

  it('显示搜索结果列表', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      expect(screen.getByTestId('goods-list')).toBeInTheDocument()

      const goodsItems = screen.getAllByTestId(/goods-item-\d+/)
      expect(goodsItems).toHaveLength(2)

      expect(screen.getByText('iPhone 15')).toBeInTheDocument()
      expect(screen.getByText('MacBook Pro')).toBeInTheDocument()
    })
  })

  it('处理搜索提交', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      const searchInput = document.querySelector('.search-input') as HTMLInputElement
      expect(searchInput).toBeInTheDocument()
    })

    // 修改搜索关键词
    const searchInput = document.querySelector('.search-input') as HTMLInputElement
    fireEvent.change(searchInput, { target: { value: 'iPad' } })

    // 提交搜索
    fireEvent.keyPress(searchInput, { key: 'Enter', code: 'Enter' })

    // 验证搜索输入框的值被更新
    await waitFor(() => {
      expect(searchInput.value).toBe('iPad')
    })

    // 验证清除按钮出现（表示有输入内容）
    await waitFor(() => {
      const clearIcon = document.querySelector('.clear-icon')
      expect(clearIcon).toBeInTheDocument()
    })
  })

  it('显示空状态', async () => {
    // Mock empty response
    const { goodsClient } = require('@/api')
    goodsClient.$get.mockResolvedValue({
      status: 200,
      json: () => Promise.resolve({
        data: [],
        pagination: {
          current: 1,
          pageSize: 10,
          total: 0,
          totalPages: 0
        }
      })
    })

    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      expect(screen.getByText('暂无相关商品')).toBeInTheDocument()
      expect(screen.getByText('换个关键词试试吧')).toBeInTheDocument()
    })
  })

  it('处理商品点击', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      const firstGoodsItem = screen.getByTestId('goods-item-0')
      fireEvent.click(firstGoodsItem)
    })

    // 验证跳转到商品详情页面
    expect(mockNavigateTo).toHaveBeenCalledWith({
      url: '/pages/goods-detail/index?id=1'
    })
  })

  it('处理添加到购物车', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      const addCartButtons = screen.getAllByTestId('add-cart-btn')
      expect(addCartButtons.length).toBeGreaterThan(0)
      fireEvent.click(addCartButtons[0])
    })

    // 验证购物车功能被调用
    expect(mockAddToCart).toHaveBeenCalledWith({
      id: 1,
      name: 'iPhone 15',
      price: 599900,
      image: 'https://example.com/iphone15.jpg',
      stock: 10,
      quantity: 1
    })
  })

  it('处理下拉刷新', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      // 模拟下拉刷新 - 直接调用onRefresherRefresh
      const scrollView = document.querySelector('.search-result-content')
      if (scrollView) {
        // 触发下拉刷新事件
        const event = new Event('refresherrefresh')
        scrollView.dispatchEvent(event)
      }
    })

    // 验证API被重新调用
    await waitFor(() => {
      const { goodsClient } = require('@/api')
      expect(goodsClient.$get).toHaveBeenCalled()
    })
  })

  it('处理清除搜索输入', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      const searchInput = document.querySelector('.search-input') as HTMLInputElement

      // 输入内容
      fireEvent.change(searchInput, { target: { value: '测试商品' } })

      // 验证清除按钮出现
      const clearIcon = document.querySelector('.clear-icon')
      expect(clearIcon).toBeInTheDocument()

      // 点击清除按钮
      fireEvent.click(clearIcon!)

      // 验证搜索输入被清空
      expect(searchInput.value).toBe('')
    })
  })

  it('验证样式类名应用', async () => {
    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      const container = document.querySelector('.search-result-page')
      expect(container).toBeInTheDocument()

      const content = document.querySelector('.search-result-content')
      expect(content).toBeInTheDocument()

      const searchBar = document.querySelector('.search-bar-container')
      expect(searchBar).toBeInTheDocument()

      const resultContainer = document.querySelector('.result-container')
      expect(resultContainer).toBeInTheDocument()

      const goodsListContainer = document.querySelector('.goods-list-container')
      expect(goodsListContainer).toBeInTheDocument()
    })
  })

  it('显示加载状态', async () => {
    // Mock loading state
    const { goodsClient } = require('@/api')
    goodsClient.$get.mockImplementation(() => new Promise(() => {})) // Never resolves

    renderWithProviders(<SearchResultPage />)

    await waitFor(() => {
      expect(screen.getByText('搜索中...')).toBeInTheDocument()
    })
  })
})