import '@testing-library/jest-dom'

import { cleanup, fireEvent, render, waitFor } from '@testing-library/react'
import { axe, toHaveNoViolations } from 'jest-axe'
import { vi } from 'vitest'

import { PktAlert } from './Alert'

expect.extend(toHaveNoViolations)

afterEach(cleanup)

describe('PktAlert', () => {
  test('calls onClose when close button is clicked', async () => {
    const onClose = vi.fn()
    const { getByLabelText } = render(
      <PktAlert closeAlert={true} onClose={onClose}>
        Hello World
      </PktAlert>,
    )
    fireEvent.click(getByLabelText('close'))
    await waitFor(() => {
      expect(onClose).toHaveBeenCalledTimes(1)
    })
  })

  test('renders with default role', async () => {
    const { getByRole } = render(<PktAlert>Alert text</PktAlert>)
    const alert = getByRole('status')
    expect(alert).toBeInTheDocument()
    expect(alert).toHaveAttribute('role', 'status')
  })

  test('renders with alert as role prop', async () => {
    const { getByRole } = render(<PktAlert role="alert">Alert text</PktAlert>)
    const alert = getByRole('alert')
    expect(alert).toBeInTheDocument()
    expect(alert).toHaveAttribute('role', 'alert')
  })

  test.each`
    camelCase      | kebabCase      | rendered
    ${'assertive'} | ${undefined}   | ${'assertive'}
    ${undefined}   | ${'assertive'} | ${'assertive'}
    ${'polite'}    | ${undefined}   | ${'polite'}
    ${undefined}   | ${undefined}   | ${'polite'}
    ${'off'}       | ${'assertive'} | ${'off'}
  `(
    'should support both ariaLive ($camelCase) and aria-live ($kebabCase) attributes ',
    async ({ camelCase, kebabCase, rendered }) => {
      const { container } = render(
        <PktAlert ariaLive={camelCase} aria-live={kebabCase}>
          Alert text
        </PktAlert>,
      )
      const elementThatHasAriaLive = container.querySelector('*[aria-live]')
      expect(elementThatHasAriaLive).toHaveAttribute('aria-live', rendered)
    },
  )

  test.each`
    title             | expected
    ${'Simple title'} | ${'Simple title'}
    ${''}             | ${undefined}
    ${null}           | ${undefined}
    ${(
    <span>
    Complex <strong>title</strong>
  </span>
  )} | ${'<span>Complex <strong>title</strong></span>'}
  `('support complex title %$', async ({title, expected}) => {
    const { container } = render(
      <PktAlert title={title}>
        Alert text
      </PktAlert>,
    )
    const titleElement = container.querySelector('.pkt-alert__title');
    expect(titleElement?.innerHTML).toEqual(expected)
  })

  describe('accessibility', () => {
    test('renders with no wcag errors with axe', async () => {
      const { container } = render(<PktAlert title="Error" skin="error"></PktAlert>)
      const results = await axe(container)

      expect(results).toHaveNoViolations()
    })
  })
})
