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()
    expect(screen.getByText('搜索')).toBeInTheDocument()
  })

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

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

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

    await waitFor(() => {
      expect(screen.getByText('搜索历史')).toBeInTheDocument()
      expect(screen.getByText('手机')).toBeInTheDocument()
      expect(screen.getByText('耳机')).toBeInTheDocument()
      expect(screen.getByText('笔记本电脑')).toBeInTheDocument()
      expect(screen.getByText('清空')).toBeInTheDocument()
    })
  })

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

    await waitFor(() => {
      expect(screen.getByText('热门搜索')).toBeInTheDocument()
      expect(screen.getByText('手机')).toBeInTheDocument()
      expect(screen.getByText('笔记本电脑')).toBeInTheDocument()
      expect(screen.getByText('耳机')).toBeInTheDocument()
      expect(screen.getByText('智能手表')).toBeInTheDocument()
    })
  })

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

    renderWithProviders(<SearchPage />)

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

  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(() => {
      const historyItem = screen.getByText('手机')
      fireEvent.click(historyItem)

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

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

    await waitFor(() => {
      const popularItem = screen.getByText('智能手表')
      fireEvent.click(popularItem)

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

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

    await waitFor(() => {
      const clearButton = screen.getByText('清空')
      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)
    })
  })
})