import { render, screen } from '@testing-library/react'
import { SelectButton } from './SelectButton'
import userEvent from '@testing-library/user-event'

test('renders a button by default', () => {
  render(<SelectButton menuItems={[]} styles={{}} />)

  expect(screen.getByRole('button')).toBeInTheDocument()
})

test('clicking the button opens a popover with the menu items', () => {
  render(<SelectButton menuItems={[{ label: 'test item 1' }, { label: 'test item 2' }]} />)

  const selectButton = screen.getByRole('button')
  userEvent.click(selectButton)

  expect(screen.getByText('test item 1')).toBeInTheDocument()
  expect(screen.getByText('test item 2')).toBeInTheDocument()
})

test('clicking on a menu item invokes the onMenuItemSelected callback with the menu item and closes the popover', () => {
  const mockOnMenuItemSelected = jest.fn()
  render(
    <SelectButton
      menuItems={[{ label: 'test item 1' }, { label: 'test item 2' }]}
      onMenuItemSelected={mockOnMenuItemSelected}
    />
  )

  const selectButton = screen.getByRole('button')
  userEvent.click(selectButton)
  const menuItem1 = screen.getByText('test item 1')
  userEvent.click(menuItem1)

  expect(mockOnMenuItemSelected).toHaveBeenCalledTimes(1)
  expect(mockOnMenuItemSelected).toHaveBeenCalledWith({ label: 'test item 1' })
  expect(screen.queryByText('test item 1')).not.toBeInTheDocument()
})

test('clicking on a menu item does not invoke the onMenuItemSelected callback when the item is already selected, and closes the popover', () => {
  const mockOnMenuItemSelected = jest.fn()
  render(
    <SelectButton
      menuItems={[{ label: 'test item 1', selected: true }, { label: 'test item 2' }]}
      onMenuItemSelected={mockOnMenuItemSelected}
    />
  )

  const selectButton = screen.getByRole('button')
  userEvent.click(selectButton)
  const menuItem1 = screen.getByText('test item 1')
  userEvent.click(menuItem1)

  expect(mockOnMenuItemSelected).not.toHaveBeenCalled()
  expect(screen.queryByText('test item 1')).not.toBeInTheDocument()
})

test('the button is disabled when the disabled property is set', () => {
  render(<SelectButton menuItems={[]} disabled />)

  expect(screen.getByRole('button')).toBeDisabled()
})

test('the popover is closed when clicking outside of it', () => {
  render(<SelectButton menuItems={[{ label: 'test item 1' }, { label: 'test item 2' }]} />)
  const selectButton = screen.getByRole('button')
  userEvent.click(selectButton)

  userEvent.click(document.body)

  expect(screen.queryByText('test item 1')).not.toBeInTheDocument()
  expect(screen.queryByText('test item 2')).not.toBeInTheDocument()
})
