import React from 'react';
import { fireEvent, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import TruncatedText, {
    Props,
    CLASS_NAME,
    Placement,
    CLASS_NAME_DISABLE_POINTER,
} from '../truncatedText';

describe('<TruncatedText>', () => {
    const defaultProps: Props = {
        maxLength: 10,
        value: 'Some very long song name 12345678910 12345678910 12345678910',
    };

    const renderComponent = (props: Partial<Props> = {}) =>
        renderInAppContext(<TruncatedText {...defaultProps} {...props} />);

    describe('when not truncated and on hover', () => {
        test("doesn't render tooltip", async () => {
            const { container, queryByRole } = renderComponent({
                maxLength: undefined,
            });

            const element = container
                .getElementsByClassName(CLASS_NAME)
                .item(0);
            if (element) fireEvent.mouseEnter(element);

            const tooltip = queryByRole('tooltip');
            await waitFor(() => {
                expect(tooltip).toBeNull();
            });
        });
    });

    describe('when truncated and on hover', () => {
        test('renders tooltip', async () => {
            const { container, findByTestId } = renderComponent();
            const element = container
                .getElementsByClassName(CLASS_NAME)
                .item(0);
            if (element) fireEvent.mouseEnter(element);

            const tooltip = await findByTestId('tooltip');
            expect(tooltip).toBeVisible();
        });
    });

    describe('when truncated and not hovering', () => {
        test("doesn't render tooltip", async () => {
            const { queryByRole } = renderComponent();

            const tooltip = queryByRole('tooltip');

            await waitFor(() => {
                expect(tooltip).toBeNull();
            });
        });
    });

    describe('when useLink prop is false', () => {
        test("doesn't render link", () => {
            const { container } = renderComponent({
                useLink: false,
            });

            const link = container.getElementsByTagName('a').item(0);
            expect(link).toBeNull();
        });
    });

    describe('when useLink prop is true', () => {
        test('renders link', () => {
            const { container } = renderComponent({
                useLink: true,
                route: 'home',
            });

            const link = container.getElementsByTagName('a').item(0);
            expect(link).toBeVisible();
        });
    });

    describe('when disableTooltipPointerEvents is not set', () => {
        test('pointer event class is not set', async () => {
            const { container } = renderComponent({
                useLink: true,
                route: 'home',
            });

            const element = container
                .getElementsByClassName(CLASS_NAME)
                .item(0);
            if (element) fireEvent.mouseEnter(element);

            await waitFor(() => {
                const result = document.getElementsByClassName(
                    CLASS_NAME_DISABLE_POINTER
                );
                expect(result.length).toBe(0);
            });
        });
    });

    describe('when disableTooltipPointerEvents is', () => {
        test('pointer event class is set', async () => {
            const { container } = renderComponent({
                useLink: true,
                route: 'home',
                disableTooltipPointerEvents: true,
            });
            const element = container
                .getElementsByClassName(CLASS_NAME)
                .item(0);
            if (element) fireEvent.mouseEnter(element);

            await waitFor(() => {
                const result = document.getElementsByClassName(
                    CLASS_NAME_DISABLE_POINTER
                );
                expect(result.length).toBe(1);
            });
        });
    });

    const toolTipPlacements: Placement[] = ['right', 'left', 'bottom', 'top'];
    describe.each(toolTipPlacements)(
        'when placement is set to "%s"',
        placement => {
            test('renders tooltip in that position', async () => {
                const { container, findByTestId } = renderComponent({
                    useLink: true,
                    route: 'home',
                    placement,
                });

                const element = container
                    .getElementsByClassName(CLASS_NAME)
                    .item(0);
                if (element) fireEvent.mouseEnter(element);

                const tooltip = await findByTestId('tooltip');
                expect(tooltip).toHaveClass('Tooltip');
            });
        }
    );
});
