import { describe, expect, it, vi } from 'vitest'
import { fireEvent, render, screen } from '@testing-library/react'

import Alert from './Alert'
import { type AlertTypes } from './Alert'
import { capitalize } from '../../services/HelperServiceTyped'

describe('Alert Component', () => {
  const alertTypes: AlertTypes[] = ['success', 'error', 'warning', 'info']

  alertTypes.forEach((type) => {
    it(`renders ${type} alert correctly with class name alert--${type}`, () => {
      const { container } = render(<Alert type={type} text='Test Message' />)

      expect(container.firstChild).toHaveClass(`alert${capitalize(type)}`)

      expect(screen.getByText('Test Message')).toBeInTheDocument()
    })
  })

  it('renders close button when close prop is provided', () => {
    const handleClose = vi.fn<() => void>()
    render(
      <Alert
        type='info'
        text='Test Message'
        close={{
          show: true,
          callout: handleClose,
        }}
      />,
    )

    const closeButton = screen.getByRole('button')
    expect(closeButton).toBeInTheDocument()
    fireEvent.click(closeButton)
    expect(handleClose).toHaveBeenCalledTimes(1)
  })

  it('shows confirmation popover when close button with confirmation is clicked', () => {
    const handleConfirm = vi.fn<() => void>()
    render(
      <Alert
        type='success'
        text='Test Message'
        close={{
          show: true,
          callout: () => {},
          confirmation: {
            header: 'Confirm Close',
            body: 'Are you sure you want to close?',
            confirmButtonText: 'Yes, close',
            confirmCallout: handleConfirm,
            type: 'green',
          },
        }}
      />,
    )

    const closeButton = screen.getAllByRole('button')[0]

    fireEvent.click(closeButton)

    expect(screen.getByText('Confirm Close')).toBeInTheDocument()
    expect(
      screen.getByText('Are you sure you want to close?'),
    ).toBeInTheDocument()
    expect(screen.getByText('Yes, close')).toBeInTheDocument()

    const confirmButton = screen.getByText('Yes, close')
    fireEvent.click(confirmButton)
    expect(handleConfirm).toHaveBeenCalledTimes(1)
  })

  it('shows button in Alert when buttons prop is provided', () => {
    const handleClick = vi.fn<() => void>()
    render(
      <Alert
        type='info'
        text='Test Alert Message'
        buttons={[
          {
            as: 'link',
            to: '/',
            routerComponent: 'a',
            children: 'Link Button',
          },
          {
            children: 'Button',
            onClick: handleClick,
          },
        ]}
      />,
    )
    const linkButton = screen.getByText('Link Button')
    const button = screen.getByText('Button')

    expect(linkButton).toBeInTheDocument()
    expect(button).toBeInTheDocument()

    fireEvent.click(button)
    expect(handleClick).toHaveBeenCalledTimes(1)
  })

  it('applies custom class when provided', () => {
    const { container } = render(
      <Alert type='success' text='Test Message' customClass='custom-alert' />,
    )

    expect(container.firstChild).toHaveClass('custom-alert')
  })
})
