import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { EmojiSelector } from './EmojiSelector'
import { EmojiSelectorOpenButtonProps } from '../models'
import React from 'react'

test('renders a button which opens a popover with default emojis', () => {
  render(<EmojiSelector onSelectEmoji={jest.fn()} />)

  const emojiSelectorToggleButton = screen.getByLabelText('Toggle emoji selector')

  expect(emojiSelectorToggleButton).toBeInTheDocument()
  userEvent.click(emojiSelectorToggleButton)
  const defaultEmojis = ['😂', '👍', '🎉', '😃', '👏']
  defaultEmojis.forEach((emoji) => {
    expect(screen.getByLabelText(`Insert ${emoji} emoji`)).toBeInTheDocument()
  })
})

test('clicking the toggle selector button while the selector is open closes the selector', () => {
  render(<EmojiSelector onSelectEmoji={jest.fn()} />)
  const emojiSelectorToggleButton = screen.getByLabelText('Toggle emoji selector')
  userEvent.click(emojiSelectorToggleButton)
  expect(screen.getByLabelText('Insert 😂 emoji')).toBeInTheDocument()

  userEvent.click(emojiSelectorToggleButton)

  expect(screen.queryByLabelText('Insert 😂 emoji')).not.toBeInTheDocument()
})

test('renders custom emojis when custom emojis are given', () => {
  render(<EmojiSelector onSelectEmoji={jest.fn()} emojis={['👍', '👎']} />)

  userEvent.click(screen.getByLabelText('Toggle emoji selector'))

  expect(screen.getByLabelText('Insert 👍 emoji')).toBeInTheDocument()
  expect(screen.getByLabelText('Insert 👎 emoji')).toBeInTheDocument()
})

test('calls onSelectEmoji with the selected emoji when an emoji is clicked', () => {
  const mockSelectEmojiHandler = jest.fn()
  render(<EmojiSelector onSelectEmoji={mockSelectEmojiHandler} />)
  userEvent.click(screen.getByLabelText('Toggle emoji selector'))

  userEvent.click(screen.getByLabelText('Insert 👍 emoji'))

  expect(mockSelectEmojiHandler).toHaveBeenCalledTimes(1)
  expect(mockSelectEmojiHandler).toHaveBeenCalledWith('👍')
})

test('when the current message becomes empty and the popover is open, it is automatically closed', () => {
  const { rerender } = render(<EmojiSelector onSelectEmoji={jest.fn()} currentMessage={'test msg'} />)
  const emojiSelectorToggleButton = screen.getByLabelText('Toggle emoji selector')
  userEvent.click(emojiSelectorToggleButton)
  expect(screen.getByLabelText('Insert 😂 emoji')).toBeInTheDocument()

  rerender(<EmojiSelector onSelectEmoji={jest.fn()} currentMessage={''} />)

  expect(screen.queryByLabelText('Insert 😂 emoji')).not.toBeInTheDocument()
})

test('clicking outside of the emoji selector closes it', () => {
  render(<EmojiSelector onSelectEmoji={jest.fn()} />)
  userEvent.click(screen.getByLabelText('Toggle emoji selector'))
  expect(screen.getByLabelText('Insert 😂 emoji')).toBeInTheDocument()

  userEvent.click(document.body)

  expect(screen.queryByLabelText('Insert 😂 emoji')).not.toBeInTheDocument()
})

test('renders a custom open selector button when given', () => {
  const DummyEmojiSelectorButton = React.forwardRef<HTMLDivElement, EmojiSelectorOpenButtonProps>(() => (
    <div data-testid='dummy-emoji-button' />
  ))
  render(<EmojiSelector onSelectEmoji={jest.fn()} components={{ OpenButton: DummyEmojiSelectorButton }} />)

  expect(screen.getByTestId('dummy-emoji-button')).toBeInTheDocument()
  expect(screen.queryByLabelText('Toggle emoji selector')).not.toBeInTheDocument()
})
