import React from 'react'
import { act, render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import ConfirmModal from './index'

// Mock external dependencies as per guidelines
jest.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}))

// Test utilities
const defaultProps = {
  show: true,
  onClose: jest.fn(),
  onConfirm: jest.fn(),
}

const renderComponent = (props: Partial<React.ComponentProps<typeof ConfirmModal>> = {}) => {
  const mergedProps = { ...defaultProps, ...props }
  return render(<ConfirmModal {...mergedProps} />)
}

describe('ConfirmModal', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  // Rendering tests (REQUIRED)
  describe('Rendering', () => {
    it('should render without crashing', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      expect(screen.getByRole('dialog')).toBeInTheDocument()
    })

    it('should render when show prop is true', () => {
      // Arrange & Act
      renderComponent({ show: true })

      // Assert
      expect(screen.getByRole('dialog')).toBeInTheDocument()
    })

    it('should not render when show prop is false', () => {
      // Arrange & Act
      renderComponent({ show: false })

      // Assert
      expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
    })

    it('should render warning icon with proper styling', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      const iconContainer = document.querySelector('.rounded-xl')
      expect(iconContainer).toBeInTheDocument()
      expect(iconContainer).toHaveClass('border-[0.5px]')
      expect(iconContainer).toHaveClass('bg-background-section')
    })

    it('should render translated title and description', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      expect(screen.getByText('tools.createTool.confirmTitle')).toBeInTheDocument()
      expect(screen.getByText('tools.createTool.confirmTip')).toBeInTheDocument()
    })

    it('should render action buttons with translated text', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      expect(screen.getByText('common.operation.cancel')).toBeInTheDocument()
      expect(screen.getByText('common.operation.confirm')).toBeInTheDocument()
    })
  })

  // Props tests (REQUIRED)
  describe('Props', () => {
    it('should handle missing onConfirm prop gracefully', () => {
      // Arrange & Act - Should not crash when onConfirm is undefined
      expect(() => {
        renderComponent({ onConfirm: undefined })
      }).not.toThrow()

      // Assert
      expect(screen.getByRole('dialog')).toBeInTheDocument()
      expect(screen.getByText('common.operation.confirm')).toBeInTheDocument()
    })

    it('should apply default styling and width constraints', () => {
      // Arrange & Act
      renderComponent()

      // Assert - Check for the dialog panel with modal content
      // The real modal structure has nested divs, we need to find the one with our classes
      const dialogContent = document.querySelector('.relative.rounded-2xl')
      expect(dialogContent).toBeInTheDocument()
      expect(dialogContent).toHaveClass('w-[600px]')
      expect(dialogContent).toHaveClass('max-w-[600px]')
      expect(dialogContent).toHaveClass('p-8')
    })
  })

  // User Interactions
  describe('User Interactions', () => {
    it('should call onClose when close button is clicked', async () => {
      // Arrange
      const user = userEvent.setup()
      const onClose = jest.fn()
      renderComponent({ onClose })

      // Act - Find the close button and click it
      const closeButton = document.querySelector('.cursor-pointer')
      expect(closeButton).toBeInTheDocument() // Ensure the button is found before clicking
      await user.click(closeButton!)

      // Assert
      expect(onClose).toHaveBeenCalledTimes(1)
    })

    it('should call onClose when cancel button is clicked', async () => {
      // Arrange
      const user = userEvent.setup()
      const onClose = jest.fn()
      renderComponent({ onClose })

      // Act
      const cancelButton = screen.getByText('common.operation.cancel')
      await user.click(cancelButton)

      // Assert
      expect(onClose).toHaveBeenCalledTimes(1)
    })

    it('should call onConfirm when confirm button is clicked', async () => {
      // Arrange
      const user = userEvent.setup()
      const onConfirm = jest.fn()
      renderComponent({ onConfirm })

      // Act
      const confirmButton = screen.getByText('common.operation.confirm')
      await user.click(confirmButton)

      // Assert
      expect(onConfirm).toHaveBeenCalledTimes(1)
    })

    it('should not throw error when confirm button is clicked without onConfirm', async () => {
      // Arrange
      const user = userEvent.setup()
      renderComponent({ onConfirm: undefined })
      const confirmButton = screen.getByText('common.operation.confirm')

      // Act & Assert - This will fail the test if user.click throws an unhandled error
      await user.click(confirmButton)
    })

    it('should have correct button variants', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      const confirmButton = screen.getByText('common.operation.confirm')
      expect(confirmButton).toHaveClass('btn-warning')
    })
  })

  // Edge Cases (REQUIRED)
  describe('Edge Cases', () => {
    it('should handle rapid show/hide toggling', async () => {
      // Arrange
      const { rerender } = renderComponent({ show: false })

      // Assert - Initially not shown
      expect(screen.queryByRole('dialog')).not.toBeInTheDocument()

      // Act - Show modal
      await act(async () => {
        rerender(<ConfirmModal {...defaultProps} show={true} />)
      })

      // Assert - Now shown
      expect(screen.getByRole('dialog')).toBeInTheDocument()

      // Act - Hide modal again
      await act(async () => {
        rerender(<ConfirmModal {...defaultProps} show={false} />)
      })

      // Assert - Hidden again (wait for transition to complete)
      await waitFor(() => {
        expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
      })
    })

    it('should handle multiple quick clicks on close button', async () => {
      // Arrange
      const user = userEvent.setup()
      const onClose = jest.fn()
      renderComponent({ onClose })

      const closeButton = document.querySelector('.cursor-pointer')
      expect(closeButton).toBeInTheDocument() // Ensure the button is found before clicking

      // Act
      await user.click(closeButton!)
      await user.click(closeButton!)
      await user.click(closeButton!)

      // Assert
      expect(onClose).toHaveBeenCalledTimes(3)
    })

    it('should handle multiple quick clicks on confirm button', async () => {
      // Arrange
      const user = userEvent.setup()
      const onConfirm = jest.fn()
      renderComponent({ onConfirm })

      // Act
      const confirmButton = screen.getByText('common.operation.confirm')
      await user.click(confirmButton)
      await user.click(confirmButton)
      await user.click(confirmButton)

      // Assert
      expect(onConfirm).toHaveBeenCalledTimes(3)
    })

    it('should handle multiple quick clicks on cancel button', async () => {
      // Arrange
      const user = userEvent.setup()
      const onClose = jest.fn()
      renderComponent({ onClose })

      // Act - Click cancel button twice
      const cancelButton = screen.getByText('common.operation.cancel')
      await user.click(cancelButton)
      await user.click(cancelButton)

      // Assert
      expect(onClose).toHaveBeenCalledTimes(2)
    })
  })

  // Accessibility tests
  describe('Accessibility', () => {
    it('should have proper button roles', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      const buttons = screen.getAllByRole('button')
      expect(buttons).toHaveLength(2)
      expect(buttons[0]).toHaveTextContent('common.operation.cancel')
      expect(buttons[1]).toHaveTextContent('common.operation.confirm')
    })

    it('should have proper text hierarchy', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      const title = screen.getByText('tools.createTool.confirmTitle')
      expect(title).toBeInTheDocument()

      const description = screen.getByText('tools.createTool.confirmTip')
      expect(description).toBeInTheDocument()
    })

    it('should have focusable interactive elements', () => {
      // Arrange & Act
      renderComponent()

      // Assert
      const buttons = screen.getAllByRole('button')
      buttons.forEach((button) => {
        expect(button).toBeEnabled()
      })
    })
  })
})
