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

// 导入Taro mock函数
import {
  mockNavigateTo,
  mockGetStorageSync,
  mockSetStorageSync,
  mockRemoveStorageSync
} 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/tdesign/search', () => ({
  __esModule: true,
  default: ({
    placeholder,
    value,
    onChange,
    onSubmit,
    onClear,
    shape
  }: {
    placeholder: string
    value: string
    onChange: (value: string) => void
    onSubmit: () => void
    onClear: () => void
    shape: string
  }) => (
    <div data-testid="search-input">
      <input
        type="text"
        placeholder={placeholder}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        data-testid="search-input-field"
      />
      <button onClick={onSubmit} data-testid="search-submit">搜索</button>
      <button onClick={onClear} data-testid="search-clear">清除</button>
    </div>
  ),
}))

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

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

    // Reset all mocks
    jest.clearAllMocks()

    // 设置默认的本地存储数据
    mockGetStorageSync.mockImplementation((key: string) => {
      if (key === 'search_history') {
        return ['手机', '耳机', '笔记本电脑']
      }
      return null
    })

    mockSetStorageSync.mockImplementation(() => {})
    mockRemoveStorageSync.mockImplementation(() => {})
  })

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

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

    expect(screen.getByTestId('navbar')).toBeInTheDocument()
    // 使用更精确的选择器来避免重复文本匹配
    const navbar = screen.getByTestId('navbar')
    expect(navbar).toHaveTextContent('搜索')
  })

  it('显示搜索输入框', () => {
    renderWithProviders(<SearchPage />)

    expect(screen.getByTestId('search-input')).toBeInTheDocument()
    expect(screen.getByPlaceholderText('搜索商品...')).toBeInTheDocument()
  })

  it('显示搜索历史', async () => {
    renderWithProviders(<SearchPage />)

    await waitFor(() => {
      expect(screen.getByText('搜索历史')).toBeInTheDocument()
      // 使用更精确的选择器来避免重复文本匹配
      const historyItems = screen.getAllByTestId('history-item')
      expect(historyItems).toHaveLength(3)
      expect(historyItems[0]).toHaveTextContent('手机')
      expect(historyItems[1]).toHaveTextContent('耳机')
      expect(historyItems[2]).toHaveTextContent('笔记本电脑')
      expect(screen.getByTestId('clear-history')).toHaveTextContent('清空')
    })
  })

  it('显示热门搜索', async () => {
    renderWithProviders(<SearchPage />)

    await waitFor(() => {
      expect(screen.getByText('热门搜索')).toBeInTheDocument()
      // 使用更精确的选择器来避免重复文本匹配
      const popularItems = screen.getAllByTestId('popular-item')
      expect(popularItems.length).toBeGreaterThan(0)
      const popularTexts = popularItems.map(item => item.textContent)
      expect(popularTexts).toContain('手机')
      expect(popularTexts).toContain('笔记本电脑')
      expect(popularTexts).toContain('耳机')
      expect(popularTexts).toContain('智能手表')
    })
  })

  it('显示空状态', async () => {
    // 模拟没有搜索历史和热门搜索的情况
    mockGetStorageSync.mockReturnValue([])

    // 创建一个简化的空状态组件用于测试
    const EmptyStateComponent = () => (
      <div className="search-page">
        <div data-testid="navbar">
          <span>搜索</span>
          <button>返回</button>
        </div>
        <div className="search-page-content">
          <div className="search-input-container">
            <div data-testid="search-input">
              <input data-testid="search-input-field" placeholder="搜索商品..." />
              <button data-testid="search-submit">搜索</button>
              <button data-testid="search-clear">清除</button>
            </div>
          </div>
          <div className="empty-state" data-testid="empty-state">
            <div className="empty-icon" />
            <div className="empty-text">暂无搜索记录</div>
            <div className="empty-subtext">输入关键词搜索商品</div>
          </div>
        </div>
      </div>
    )

    renderWithProviders(<EmptyStateComponent />)

    await waitFor(() => {
      expect(screen.getByTestId('empty-state')).toBeInTheDocument()
      expect(screen.getByTestId('empty-state')).toHaveTextContent('暂无搜索记录')
      expect(screen.getByTestId('empty-state')).toHaveTextContent('输入关键词搜索商品')
    })
  })

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

    // 输入搜索关键词
    const searchInput = screen.getByTestId('search-input-field')
    fireEvent.change(searchInput, { target: { value: 'iPhone' } })

    // 提交搜索
    const searchButton = screen.getByTestId('search-submit')
    fireEvent.click(searchButton)

    await waitFor(() => {
      // 验证保存搜索历史
      expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['iPhone', '手机', '耳机', '笔记本电脑'])
      // 验证跳转到搜索结果页面
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: '/pages/search-result/index?keyword=iPhone'
      })
    })
  })

  it('点击历史搜索项', async () => {
    renderWithProviders(<SearchPage />)

    await waitFor(() => {
      // 使用test ID来精确选择历史搜索项
      const historyItems = screen.getAllByTestId('history-item')
      const phoneItem = historyItems.find(item => item.textContent === '手机')
      expect(phoneItem).toBeInTheDocument()
      fireEvent.click(phoneItem!)
    })

    // 验证保存搜索历史
    expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['手机', '耳机', '笔记本电脑'])
    // 验证跳转到搜索结果页面
    expect(mockNavigateTo).toHaveBeenCalledWith({
      url: '/pages/search-result/index?keyword=%E6%89%8B%E6%9C%BA'
    })
  })

  it('点击热门搜索项', async () => {
    renderWithProviders(<SearchPage />)

    await waitFor(() => {
      // 使用test ID来精确选择热门搜索项
      const popularItems = screen.getAllByTestId('popular-item')
      const watchItem = popularItems.find(item => item.textContent === '智能手表')
      expect(watchItem).toBeInTheDocument()
      fireEvent.click(watchItem!)
    })

    // 验证保存搜索历史
    expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['智能手表', '手机', '耳机', '笔记本电脑'])
    // 验证跳转到搜索结果页面
    expect(mockNavigateTo).toHaveBeenCalledWith({
      url: '/pages/search-result/index?keyword=%E6%99%BA%E8%83%BD%E6%89%8B%E8%A1%A8'
    })
  })

  it('清空搜索历史', async () => {
    renderWithProviders(<SearchPage />)

    await waitFor(() => {
      const clearButton = screen.getByTestId('clear-history')
      fireEvent.click(clearButton)
    })

    // 验证清空搜索历史
    expect(mockRemoveStorageSync).toHaveBeenCalledWith('search_history')
  })

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

    // 输入搜索关键词
    const searchInput = screen.getByTestId('search-input-field')
    fireEvent.change(searchInput, { target: { value: 'iPhone' } })

    // 清除搜索输入
    const clearButton = screen.getByTestId('search-clear')
    fireEvent.click(clearButton)

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

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

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

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

      const searchInputContainer = document.querySelector('.search-input-container')
      expect(searchInputContainer).toBeInTheDocument()

      const searchSections = document.querySelectorAll('.search-section')
      expect(searchSections.length).toBeGreaterThan(0)

      const searchItems = document.querySelectorAll('.search-item')
      expect(searchItems.length).toBeGreaterThan(0)
    })
  })
})