import React from 'react';
import userEvent from '@testing-library/user-event';

import { act } from 'react-dom/test-utils';
import { fireEvent } from '@testing-library/react';
import renderWithTheme from '../../../testUtils/renderWithTheme';

import Tooltip from '../index';

describe('Tooltip', () => {
  it('renders target and shows content while hovering', async () => {
    const { getByText, queryByText } = renderWithTheme(
      <Tooltip target={<p>Tooltip target</p>} content="Tooltip content" />
    );

    expect(getByText('Tooltip target')).toBeInTheDocument();
    expect(queryByText('Tooltip content')).not.toBeInTheDocument();

    await act(async () => {
      userEvent.hover(getByText('Tooltip target'));
    });
    expect(getByText('Tooltip content')).toBeInTheDocument();
  });

  it('renders target and shows content on touch start', async () => {
    const { getByText, queryByText } = renderWithTheme(
      <Tooltip target={<p>Tooltip target</p>} content="Tooltip content" />
    );

    expect(getByText('Tooltip target')).toBeInTheDocument();
    expect(queryByText('Tooltip content')).not.toBeInTheDocument();

    await act(async () => {
      fireEvent.touchStart(getByText('Tooltip target'));
    });
    expect(getByText('Tooltip content')).toBeInTheDocument();
  });

  it('renders target and do not shows content while hovering when visible is false', async () => {
    const { getByText, queryByText } = renderWithTheme(
      <Tooltip
        target={<p>Tooltip target</p>}
        content="Tooltip content"
        visible={false}
      />
    );

    expect(getByText('Tooltip target')).toBeInTheDocument();
    expect(queryByText('Tooltip content')).not.toBeInTheDocument();

    await act(async () => {
      userEvent.hover(getByText('Tooltip target'));
    });
    expect(queryByText('Tooltip content')).not.toBeInTheDocument();
  });

  it('allow interacting on tooltip content', async () => {
    const spiedOnClick = jest.fn();

    const { getByText, queryByText } = renderWithTheme(
      <Tooltip
        target={<p>Tooltip target</p>}
        content={
          <div>
            Tooltip with a
            <button type="submit" onClick={spiedOnClick}>
              button
            </button>
          </div>
        }
        interactive
      />
    );

    expect(getByText('Tooltip target')).toBeInTheDocument();
    expect(queryByText('Tooltip content')).not.toBeInTheDocument();

    await act(async () => {
      userEvent.hover(getByText('Tooltip target'));
    });

    expect(getByText(/Tooltip with a/)).toBeInTheDocument();

    await act(async () => {
      userEvent.unhover(getByText('Tooltip target'));
      userEvent.hover(getByText('button'));
    });

    expect(getByText(/Tooltip with a/)).toBeInTheDocument();
    userEvent.click(getByText('button'));

    expect(spiedOnClick).toHaveBeenCalledTimes(1);
  });

  it('clears timeout on unmount', async () => {
    const clearTimeoutSpy = jest.spyOn(window, 'clearTimeout');
    const { unmount } = renderWithTheme(
      <Tooltip
        target={<p>Tooltip target</p>}
        content={<div>Tooltip content</div>}
      />
    );
    unmount();

    expect(clearTimeoutSpy).toHaveBeenCalledTimes(1);
  });
});
