import { useState } from 'react'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { ThemeProvider } from 'styled-components'

import { Tooltip } from './tooltip'
import { theme } from './theme.js'

describe('<Tooltip />', () => {
  it('renders tooltip content by default when hovered', async () => {
    const { asFragment } = render(
      <ThemeProvider theme={theme}>
        <Tooltip>This is my tooltip content</Tooltip>
      </ThemeProvider>
    )

    expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
    expect(asFragment()).toMatchSnapshot()

    fireEvent.mouseOver(screen.getByTestId('tooltip:target'))
    await waitFor(() => {
      expect(screen.getByRole('tooltip')).toBeInTheDocument()
    })
    expect(screen.getByTestId('tooltip:content')).toBeInTheDocument()

    fireEvent.mouseLeave(screen.getByTestId('tooltip:target'))
    await waitFor(() => {
      expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
    })
    expect(screen.queryByTestId('tooltip:content')).not.toBeInTheDocument()
  })

  it('renders when controlled', async () => {
    const ControlledTooltip = () => {
      const [open, setOpen] = useState(false)
      return (
        <ThemeProvider theme={theme}>
          <Tooltip open={open} placement="top">
            This is my tooltip content
          </Tooltip>
          <button onClick={() => setOpen(!open)}>Click me</button>
        </ThemeProvider>
      )
    }

    render(<ControlledTooltip />)

    expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()

    fireEvent.mouseOver(screen.getByTestId('tooltip'))
    await waitFor(() => {
      expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
    })
    expect(screen.queryByTestId('tooltip:content')).not.toBeInTheDocument()

    fireEvent.click(screen.getByText('Click me'))
    await waitFor(() => {
      expect(screen.getByTestId('tooltip:content')).toHaveTextContent('This is my tooltip content')
    })

    fireEvent.click(screen.getByText('Click me'))
    await waitFor(() => {
      expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
    })
    expect(screen.queryByTestId('tooltip:content')).not.toBeInTheDocument()
  })

  it('renders with custom icon name', () => {
    render(
      <ThemeProvider theme={theme}>
        <Tooltip iconName="feedback/flag">This is my tooltip content</Tooltip>
      </ThemeProvider>
    )

    expect(screen.getByTestId('icon:feedback/flag')).toBeInTheDocument()
  })

  it('renders with custom target', () => {
    const Target = () => <div data-testid="custom-target">hover me</div>
    const { asFragment } = render(
      <ThemeProvider theme={theme}>
        <Tooltip target={<Target />}>This is my tooltip content</Tooltip>
      </ThemeProvider>
    )

    expect(screen.getByTestId('custom-target')).toBeInTheDocument()
    expect(asFragment()).toMatchSnapshot()
  })
})
