import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { AreaCascader } from '../../src/components/AreaCascader'

// Mock API 客户端
const mockAreaClient = {
  provinces: {
    $get: jest.fn()
  },
  cities: {
    $get: jest.fn()
  },
  districts: {
    $get: jest.fn()
  }
}

jest.mock('../../src/api', () => ({
  areaClient: mockAreaClient
}))

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

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

// 模拟数据
const mockProvinces = {
  success: true,
  data: {
    provinces: [
      { id: 1, name: '北京市' },
      { id: 2, name: '上海市' },
      { id: 3, name: '广东省' }
    ]
  },
  message: ''
}

const mockCities = {
  success: true,
  data: {
    cities: [
      { id: 11, name: '北京市' },
      { id: 12, name: '朝阳区' },
      { id: 13, name: '海淀区' }
    ]
  },
  message: ''
}

const mockDistricts = {
  success: true,
  data: {
    districts: [
      { id: 101, name: '朝阳区' },
      { id: 102, name: '海淀区' },
      { id: 103, name: '西城区' }
    ]
  },
  message: ''
}

describe('AreaCascader 组件', () => {
  beforeEach(() => {
    // 重置所有 mock
    jest.clearAllMocks()

    // 设置默认的 mock 返回值
    mockAreaClient.provinces.$get.mockResolvedValue({
      status: 200,
      json: async () => mockProvinces
    })

    mockAreaClient.cities.$get.mockResolvedValue({
      status: 200,
      json: async () => mockCities
    })

    mockAreaClient.districts.$get.mockResolvedValue({
      status: 200,
      json: async () => mockDistricts
    })
  })

  test('应该正确渲染组件', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader onChange={onChange} />
      </Wrapper>
    )

    // 检查选择器标签
    expect(screen.getByText('省份')).toBeInTheDocument()
    expect(screen.getByText('城市')).toBeInTheDocument()
    expect(screen.getByText('区县')).toBeInTheDocument()

    // 检查默认占位符
    expect(screen.getByText('请选择省市区')).toBeInTheDocument()

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })
  })

  test('应该显示自定义占位符', () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader
          onChange={onChange}
          placeholder="选择出发地"
        />
      </Wrapper>
    )

    expect(screen.getByText('选择出发地')).toBeInTheDocument()
  })

  test('应该初始化选择值', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader
          value={[1, 11, 101]}
          onChange={onChange}
        />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    // 检查是否调用了城市和区县查询
    await waitFor(() => {
      expect(mockAreaClient.cities.$get).toHaveBeenCalledWith({
        query: { provinceId: 1 }
      })
    })

    await waitFor(() => {
      expect(mockAreaClient.districts.$get).toHaveBeenCalledWith({
        query: { cityId: 11 }
      })
    })
  })

  test('应该处理省份选择', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader onChange={onChange} />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    // 模拟选择省份
    const provincePicker = screen.getByText('请选择省份')
    fireEvent.click(provincePicker)

    // 这里我们模拟 Picker 的 onChange 事件
    // 在实际测试中，可能需要更复杂的模拟
  })

  test('应该正确显示已选择的省市区文本', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader
          value={[1, 11, 101]}
          onChange={onChange}
        />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    await waitFor(() => {
      expect(mockAreaClient.cities.$get).toHaveBeenCalled()
    })

    await waitFor(() => {
      expect(mockAreaClient.districts.$get).toHaveBeenCalled()
    })

    // 检查显示文本
    await waitFor(() => {
      expect(screen.getByText('北京市 北京市 朝阳区')).toBeInTheDocument()
    })
  })

  test('应该处理部分选择的情况', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader
          value={[1, 11]} // 只选择了省份和城市
          onChange={onChange}
        />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    await waitFor(() => {
      expect(mockAreaClient.cities.$get).toHaveBeenCalled()
    })

    // 检查显示文本
    await waitFor(() => {
      expect(screen.getByText('北京市 北京市')).toBeInTheDocument()
    })
  })

  test('应该处理只有省份选择的情况', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader
          value={[1]} // 只选择了省份
          onChange={onChange}
        />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    // 检查显示文本
    await waitFor(() => {
      expect(screen.getByText('北京市')).toBeInTheDocument()
    })
  })

  test('应该处理 API 错误', async () => {
    // 模拟 API 错误
    mockAreaClient.provinces.$get.mockResolvedValue({
      status: 500,
      json: async () => ({ success: false, message: '服务器错误' })
    })

    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader onChange={onChange} />
      </Wrapper>
    )

    // 组件应该正常渲染，即使 API 调用失败
    expect(screen.getByText('省份')).toBeInTheDocument()

    // 等待 API 调用
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })
  })

  test('应该禁用城市选择器当没有选择省份时', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader onChange={onChange} />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    // 检查城市选择器是否被禁用
    const cityPicker = screen.getByText('请选择城市')
    expect(cityPicker.parentElement).toHaveClass('bg-gray-100')
    expect(cityPicker.parentElement).toHaveClass('text-gray-400')
  })

  test('应该禁用区县选择器当没有选择城市时', async () => {
    const onChange = jest.fn()

    render(
      <Wrapper>
        <AreaCascader onChange={onChange} />
      </Wrapper>
    )

    // 等待数据加载
    await waitFor(() => {
      expect(mockAreaClient.provinces.$get).toHaveBeenCalled()
    })

    // 检查区县选择器是否被禁用
    const districtPicker = screen.getByText('请选择区县')
    expect(districtPicker.parentElement).toHaveClass('bg-gray-100')
    expect(districtPicker.parentElement).toHaveClass('text-gray-400')
  })
})