import { render, fireEvent } from '@testing-library/react'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter
} from '@/components/ui/dialog'

describe('Dialog 组件', () => {
  const mockOnOpenChange = jest.fn()

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

  describe('Dialog 主组件', () => {
    it('应该渲染对话框当 open 为 true 时', () => {
      const { getByText } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <div>对话框内容</div>
        </Dialog>
      )

      expect(getByText('对话框内容')).toBeTruthy()
    })

    it('不应该渲染对话框当 open 为 false 时', () => {
      const { queryByText } = render(
        <Dialog open={false} onOpenChange={mockOnOpenChange}>
          <div>对话框内容</div>
        </Dialog>
      )

      expect(queryByText('对话框内容')).toBeNull()
    })

    it('应该调用 onOpenChange(false) 当点击背景遮罩时', () => {
      const { container } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <div>对话框内容</div>
        </Dialog>
      )

      // 找到背景遮罩元素
      const backdrop = container.querySelector('.fixed')
      expect(backdrop).toBeTruthy()

      if (backdrop) {
        fireEvent.click(backdrop)
        expect(mockOnOpenChange).toHaveBeenCalledWith(false)
      }
    })

    it('不应该调用 onOpenChange 当点击内容区域时', () => {
      const { getByText } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <div>对话框内容</div>
        </Dialog>
      )

      const content = getByText('对话框内容')
      fireEvent.click(content)

      expect(mockOnOpenChange).not.toHaveBeenCalled()
    })

    it('应该应用正确的样式类名', () => {
      const { container } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <div>对话框内容</div>
        </Dialog>
      )

      const backdrop = container.querySelector('.fixed')
      const content = container.querySelector('.bg-white')

      expect(backdrop).toBeTruthy()
      expect(content).toBeTruthy()
      expect(backdrop).toHaveClass('fixed', 'inset-0', 'z-50', 'flex', 'items-center', 'justify-center', 'bg-black/50')
      expect(content).toHaveClass('bg-white', 'rounded-lg', 'shadow-lg', 'max-w-md', 'w-full', 'mx-4')
    })
  })

  describe('DialogContent 组件', () => {
    it('应该渲染内容并应用类名', () => {
      const { getByText, container } = render(
        <DialogContent className="custom-class">
          对话框内容
        </DialogContent>
      )

      const content = getByText('对话框内容')
      expect(content).toBeTruthy()

      // 直接检查包含内容的div元素
      const contentDiv = container.querySelector('div')
      expect(contentDiv).toBeTruthy()
      expect(contentDiv).toHaveClass('p-6', 'custom-class')
    })

    it('应该使用默认类名', () => {
      const { getByText, container } = render(
        <DialogContent>
          对话框内容
        </DialogContent>
      )

      const content = getByText('对话框内容')
      expect(content).toBeTruthy()

      // 直接检查包含内容的div元素
      const contentDiv = container.querySelector('div')
      expect(contentDiv).toBeTruthy()
      expect(contentDiv).toHaveClass('p-6')
    })
  })

  describe('DialogHeader 组件', () => {
    it('应该渲染头部并应用类名', () => {
      const { getByText, container } = render(
        <DialogHeader className="custom-header">
          对话框头部
        </DialogHeader>
      )

      const header = getByText('对话框头部')
      expect(header).toBeTruthy()

      // 直接检查包含头部的div元素
      const headerDiv = container.querySelector('div')
      expect(headerDiv).toBeTruthy()
      expect(headerDiv).toHaveClass('mb-4', 'custom-header')
    })

    it('应该使用默认类名', () => {
      const { getByText, container } = render(
        <DialogHeader>
          对话框头部
        </DialogHeader>
      )

      const header = getByText('对话框头部')
      expect(header).toBeTruthy()

      // 直接检查包含头部的div元素
      const headerDiv = container.querySelector('div')
      expect(headerDiv).toBeTruthy()
      expect(headerDiv).toHaveClass('mb-4')
    })
  })

  describe('DialogTitle 组件', () => {
    it('应该渲染标题并应用类名', () => {
      const { getByText } = render(
        <DialogTitle className="custom-title">
          对话框标题
        </DialogTitle>
      )

      const title = getByText('对话框标题')
      expect(title).toBeTruthy()
      expect(title).toHaveClass('text-lg', 'font-semibold', 'text-gray-900', 'custom-title')
    })

    it('应该使用默认类名', () => {
      const { getByText } = render(
        <DialogTitle>
          对话框标题
        </DialogTitle>
      )

      const title = getByText('对话框标题')
      expect(title).toHaveClass('text-lg', 'font-semibold', 'text-gray-900')
    })
  })

  describe('DialogDescription 组件', () => {
    it('应该渲染描述并应用类名', () => {
      const { getByText } = render(
        <DialogDescription className="custom-desc">
          对话框描述
        </DialogDescription>
      )

      const description = getByText('对话框描述')
      expect(description).toBeTruthy()
      expect(description).toHaveClass('text-sm', 'text-gray-600', 'custom-desc')
    })

    it('应该使用默认类名', () => {
      const { getByText } = render(
        <DialogDescription>
          对话框描述
        </DialogDescription>
      )

      const description = getByText('对话框描述')
      expect(description).toHaveClass('text-sm', 'text-gray-600')
    })
  })

  describe('DialogFooter 组件', () => {
    it('应该渲染底部并应用类名', () => {
      const { getByText, container } = render(
        <DialogFooter className="custom-footer">
          对话框底部
        </DialogFooter>
      )

      const footer = getByText('对话框底部')
      expect(footer).toBeTruthy()

      // 直接检查包含底部的div元素
      const footerDiv = container.querySelector('div')
      expect(footerDiv).toBeTruthy()
      expect(footerDiv).toHaveClass('flex', 'justify-end', 'space-x-2', 'custom-footer')
    })

    it('应该使用默认类名', () => {
      const { getByText, container } = render(
        <DialogFooter>
          对话框底部
        </DialogFooter>
      )

      const footer = getByText('对话框底部')
      expect(footer).toBeTruthy()

      // 直接检查包含底部的div元素
      const footerDiv = container.querySelector('div')
      expect(footerDiv).toBeTruthy()
      expect(footerDiv).toHaveClass('flex', 'justify-end', 'space-x-2')
    })
  })

  describe('完整对话框示例', () => {
    it('应该渲染完整的对话框结构', () => {
      const { getByText } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>确认操作</DialogTitle>
              <DialogDescription>
                您确定要执行此操作吗？
              </DialogDescription>
            </DialogHeader>
            <DialogFooter>
              <button>取消</button>
              <button>确认</button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      )

      expect(getByText('确认操作')).toBeTruthy()
      expect(getByText('您确定要执行此操作吗？')).toBeTruthy()
      expect(getByText('取消')).toBeTruthy()
      expect(getByText('确认')).toBeTruthy()
    })

    it('应该正确处理事件冒泡', () => {
      const { getByText } = render(
        <Dialog open={true} onOpenChange={mockOnOpenChange}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>测试事件</DialogTitle>
            </DialogHeader>
            <button onClick={() => {}}>测试按钮</button>
          </DialogContent>
        </Dialog>
      )

      const button = getByText('测试按钮')
      fireEvent.click(button)

      // 点击按钮不应该触发对话框关闭
      expect(mockOnOpenChange).not.toHaveBeenCalled()
    })
  })
})