import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import HomePage from '../../src/pages/home/index'

// Mock Taro 导航
const mockNavigateTo = jest.fn()
jest.mock('@tarojs/taro', () => ({
  navigateTo: mockNavigateTo
}))

// Mock AreaPicker 组件
jest.mock('../../src/components/AreaPicker', () => ({
  AreaPicker: jest.fn(({ visible, onClose, onConfirm, value, title }) => {
    if (!visible) return null

    return (
      <div data-testid="area-picker">
        <div data-testid="area-picker-title">{title}</div>
        <button data-testid="area-picker-confirm" onClick={() => onConfirm([1, 11, 101], [
          { id: 1, name: '北京市', type: 'province' },
          { id: 11, name: '北京市', type: 'city' },
          { id: 101, name: '朝阳区', type: 'district' }
        ])}>确认</button>
        <button data-testid="area-picker-cancel" onClick={onClose}>取消</button>
      </div>
    )
  })
}))

// Mock TabBarLayout 组件
jest.mock('@/layouts/tab-bar-layout', () => ({
  TabBarLayout: jest.fn(({ children, activeKey, className }) => (
    <div data-testid="tab-bar-layout" data-active-key={activeKey} className={className}>
      {children}
    </div>
  ))
}))

// 创建测试用的 QueryClient
const createTestQueryClient = () => new QueryClient({
  defaultOptions: {
    queries: {
      retry: false,
    },
  },
})

// 包装组件
const Wrapper = ({ children }: { children: React.ReactNode }) => {
  const queryClient = createTestQueryClient()
  return (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  )
}

describe('首页组合查询逻辑测试', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  describe('组合查询映射逻辑', () => {
    test('应该正确映射大巴拼车组合查询参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 默认选择大巴拼车，点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证导航参数
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('vehicleType=bus')
      })
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('travelMode=carpool')
      })
    })

    test('应该正确映射商务车组合查询参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 选择商务车
      const businessOption = screen.getByText('商务车')
      fireEvent.click(businessOption)

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证导航参数 - 商务车支持拼车和包车两种出行方式
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('vehicleType=business')
      })
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('travelMode=carpool,charter')
      })
    })

    test('应该正确映射包车组合查询参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 选择包车
      const charterOption = screen.getByText('包车')
      fireEvent.click(charterOption)

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证导航参数 - 包车支持大巴和商务车两种车型
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('vehicleType=bus,business')
      })
      expect(mockNavigateTo).toHaveBeenCalledWith({
        url: expect.stringContaining('travelMode=charter')
      })
    })

    test('应该正确显示组合查询选项', () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 验证三个组合查询选项都存在
      expect(screen.getByText('大巴拼车')).toBeInTheDocument()
      expect(screen.getByText('商务车')).toBeInTheDocument()
      expect(screen.getByText('包车')).toBeInTheDocument()
    })

    test('应该正确显示组合查询选项的选中状态', () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 默认选中大巴拼车
      const busOption = screen.getByText('大巴拼车')
      expect(busOption.parentElement).toHaveClass('bg-gradient-to-r')
      expect(busOption.parentElement).toHaveClass('text-white')

      // 选择商务车
      const businessOption = screen.getByText('商务车')
      fireEvent.click(businessOption)

      // 验证商务车被选中，大巴拼车取消选中
      expect(businessOption.parentElement).toHaveClass('bg-gradient-to-r')
      expect(businessOption.parentElement).toHaveClass('text-white')
      expect(busOption.parentElement).not.toHaveClass('text-white')
    })
  })

  describe('组合查询参数传递', () => {
    test('应该正确传递完整的组合查询参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 选择包车
      const charterOption = screen.getByText('包车')
      fireEvent.click(charterOption)

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证完整的导航参数
      const navigateCall = mockNavigateTo.mock.calls[0][0]
      const url = navigateCall.url

      expect(url).toContain('startAreaIds=[1,11,101]')
      expect(url).toContain('endAreaIds=[1,11,101]')
      expect(url).toContain('date=')
      expect(url).toContain('vehicleType=bus,business')
      expect(url).toContain('travelMode=charter')
    })

    test('应该正确传递商务车多值出行方式参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 选择商务车
      const businessOption = screen.getByText('商务车')
      fireEvent.click(businessOption)

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证商务车支持多值出行方式参数
      const navigateCall = mockNavigateTo.mock.calls[0][0]
      const url = navigateCall.url

      expect(url).toContain('vehicleType=business')
      expect(url).toContain('travelMode=carpool,charter')
    })

    test('应该正确传递包车多值车型参数', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 选择包车
      const charterOption = screen.getByText('包车')
      fireEvent.click(charterOption)

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证包车支持多值车型参数
      const navigateCall = mockNavigateTo.mock.calls[0][0]
      const url = navigateCall.url

      expect(url).toContain('vehicleType=bus,business')
      expect(url).toContain('travelMode=charter')
    })
  })

  describe('组合查询样式验证', () => {
    test('应该为不同组合查询选项应用正确的样式', () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      const busOption = screen.getByText('大巴拼车')
      const businessOption = screen.getByText('商务车')
      const charterOption = screen.getByText('包车')

      // 默认选中大巴拼车
      expect(busOption.parentElement).toHaveClass('bg-gradient-to-r')
      expect(busOption.parentElement).toHaveClass('text-white')

      // 选择商务车
      fireEvent.click(businessOption)
      expect(businessOption.parentElement).toHaveClass('bg-gradient-to-r')
      expect(businessOption.parentElement).toHaveClass('text-white')

      // 选择包车
      fireEvent.click(charterOption)
      expect(charterOption.parentElement).toHaveClass('bg-gradient-to-r')
      expect(charterOption.parentElement).toHaveClass('text-white')
    })

    test('应该正确切换组合查询选项的选中状态', () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      const busOption = screen.getByText('大巴拼车')
      const businessOption = screen.getByText('商务车')
      const charterOption = screen.getByText('包车')

      // 初始状态：大巴拼车选中
      expect(busOption.parentElement).toHaveClass('text-white')
      expect(businessOption.parentElement).not.toHaveClass('text-white')
      expect(charterOption.parentElement).not.toHaveClass('text-white')

      // 选择商务车
      fireEvent.click(businessOption)
      expect(busOption.parentElement).not.toHaveClass('text-white')
      expect(businessOption.parentElement).toHaveClass('text-white')
      expect(charterOption.parentElement).not.toHaveClass('text-white')

      // 选择包车
      fireEvent.click(charterOption)
      expect(busOption.parentElement).not.toHaveClass('text-white')
      expect(businessOption.parentElement).not.toHaveClass('text-white')
      expect(charterOption.parentElement).toHaveClass('text-white')
    })
  })

  describe('组合查询边界情况', () => {
    test('应该正确处理默认组合查询参数', () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 验证默认参数
      const busOption = screen.getByText('大巴拼车')
      expect(busOption.parentElement).toHaveClass('text-white')

      // 验证默认参数设置
      expect(mockNavigateTo).not.toHaveBeenCalled()
    })

    test('应该正确处理组合查询参数变化', async () => {
      render(
        <Wrapper>
          <HomePage />
        </Wrapper>
      )

      // 设置出发地和目的地
      const startLocationButton = screen.getByText('出发地').closest('button')
      fireEvent.click(startLocationButton!)
      const confirmButton = screen.getByTestId('area-picker-confirm')
      fireEvent.click(confirmButton)

      const endLocationButton = screen.getByText('目的地').closest('button')
      fireEvent.click(endLocationButton!)
      fireEvent.click(confirmButton)

      // 等待状态更新
      await waitFor(() => {
        expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2)
      })

      // 测试从大巴拼车切换到商务车
      const busOption = screen.getByText('大巴拼车')
      const businessOption = screen.getByText('商务车')

      // 初始选择大巴拼车
      expect(busOption.parentElement).toHaveClass('text-white')

      // 切换到商务车
      fireEvent.click(businessOption)
      expect(businessOption.parentElement).toHaveClass('text-white')
      expect(busOption.parentElement).not.toHaveClass('text-white')

      // 点击查询
      const searchButton = screen.getByText('查询路线')
      fireEvent.click(searchButton)

      // 验证商务车参数
      const navigateCall = mockNavigateTo.mock.calls[0][0]
      const url = navigateCall.url

      expect(url).toContain('vehicleType=business')
      expect(url).toContain('travelMode=carpool,charter')
      expect(url).not.toContain('vehicleType=bus')
      expect(url).not.toContain('travelMode=carpool')
    })
  })
})