import { render, fireEvent } from '@testing-library/react'
import Taro from '@tarojs/taro'
import CancelReasonDialog from '@/components/common/CancelReasonDialog'

// Mock Taro API
jest.mock('@tarojs/taro', () => ({
  showToast: jest.fn()
}))

describe('CancelReasonDialog', () => {
  const defaultProps = {
    visible: true,
    onCancel: jest.fn(),
    onConfirm: jest.fn(),
    loading: false
  }

  beforeEach(() => {
    jest.clearAllMocks()
  })

  it('should render dialog when visible is true', () => {
    const { getByText } = render(<CancelReasonDialog {...defaultProps} />)

    expect(getByText('取消订单')).toBeTruthy()
    expect(getByText('请选择或填写取消原因：')).toBeTruthy()
    expect(getByText('我不想买了')).toBeTruthy()
    expect(getByText('信息填写错误，重新下单')).toBeTruthy()
    expect(getByText('商家缺货')).toBeTruthy()
    expect(getByText('价格不合适')).toBeTruthy()
    expect(getByText('其他原因')).toBeTruthy()
  })

  it('should not render dialog when visible is false', () => {
    const { queryByText } = render(
      <CancelReasonDialog {...defaultProps} visible={false} />
    )

    expect(queryByText('取消订单')).toBeNull()
  })

  it('should select predefined reason when clicked', () => {
    const { getByText } = render(<CancelReasonDialog {...defaultProps} />)

    const reasonOption = getByText('我不想买了')
    fireEvent.click(reasonOption)

    // 检查样式变化（这里需要根据实际实现调整）
    expect(reasonOption).toBeTruthy()
  })

  it('should call onConfirm with reason when confirm button is clicked', () => {
    const { getByText } = render(<CancelReasonDialog {...defaultProps} />)

    const reasonOption = getByText('我不想买了')
    fireEvent.click(reasonOption)

    const confirmButton = getByText('确认取消')
    fireEvent.click(confirmButton)

    expect(defaultProps.onConfirm).toHaveBeenCalledWith('我不想买了')
  })

  it('should call onCancel when cancel button is clicked', () => {
    const { getByText } = render(<CancelReasonDialog {...defaultProps} />)

    const cancelButton = getByText('取消')
    fireEvent.click(cancelButton)

    expect(defaultProps.onCancel).toHaveBeenCalled()
  })

  it('should show error when confirming with empty reason', () => {
    const mockShowToast = Taro.showToast as jest.Mock
    const { getByText } = render(<CancelReasonDialog {...defaultProps} />)

    const confirmButton = getByText('确认取消')
    fireEvent.click(confirmButton)

    expect(mockShowToast).toHaveBeenCalledWith({
      title: '请填写取消原因',
      icon: 'error',
      duration: 2000
    })
    expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  })

  it('should show error when reason exceeds 500 characters', () => {
    const mockShowToast = Taro.showToast as jest.Mock
    const { getByPlaceholderText, getByText } = render(
      <CancelReasonDialog {...defaultProps} />
    )

    const input = getByPlaceholderText('请输入其他取消原因...')
    fireEvent.input(input, { target: { value: 'a'.repeat(501) } })

    const confirmButton = getByText('确认取消')
    fireEvent.click(confirmButton)

    expect(mockShowToast).toHaveBeenCalledWith({
      title: '取消原因不能超过500字',
      icon: 'error',
      duration: 2000
    })
    expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  })

  it('should handle custom reason input', () => {
    const { getByPlaceholderText, getByText } = render(
      <CancelReasonDialog {...defaultProps} />
    )

    const input = getByPlaceholderText('请输入其他取消原因...')
    fireEvent.input(input, { target: { value: '自定义取消原因' } })

    const confirmButton = getByText('确认取消')
    fireEvent.click(confirmButton)

    expect(defaultProps.onConfirm).toHaveBeenCalledWith('自定义取消原因')
  })

  it('should show loading state when loading is true', () => {
    const { getByText } = render(
      <CancelReasonDialog {...defaultProps} loading={true} />
    )

    expect(getByText('提交中...')).toBeTruthy()
  })

  it('should disable buttons when loading is true', () => {
    const { getByText } = render(
      <CancelReasonDialog {...defaultProps} loading={true} />
    )

    const cancelButton = getByText('取消')
    const confirmButton = getByText('提交中...')

    // 检查按钮是否被禁用（这里需要根据实际实现调整）
    expect(cancelButton).toBeTruthy()
    expect(confirmButton).toBeTruthy()
  })

  it('should reset state when dialog is closed', () => {
    const { getByText, rerender } = render(
      <CancelReasonDialog {...defaultProps} />
    )

    const reasonOption = getByText('我不想买了')
    fireEvent.click(reasonOption)

    // 重新渲染关闭的对话框
    rerender(<CancelReasonDialog {...defaultProps} visible={false} />)
    rerender(<CancelReasonDialog {...defaultProps} visible={true} />)

    // 检查状态是否重置
    const confirmButton = getByText('确认取消')
    fireEvent.click(confirmButton)

    expect(Taro.showToast).toHaveBeenCalledWith({
      title: '请填写取消原因',
      icon: 'error',
      duration: 2000
    })
  })
})