import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { render, RenderResult, fireEvent, waitForElement, getByText } from '@testing-library/react';
import { formatMessage } from '@orchard/frontend-localization';
import { formatNumber } from 'src/utils/formatNumber';
import SourceOfStreamsChart, { Props, createChartOptions } from '../Chart';

describe('<SourceOfStreamsChart>', () => {
    const defaultProps: Props = {
        series: []
    };

    const series1 = {
        name: 'THIS IS SERIES ONE!',
        collection: { value: 1, total: 1 },
        active: { value: 21, total: 21 },
        passive: { value: 31, total: 31 },
        unknown: { value: 5, total: 5 },
        subscription: { value: 0, total: 0 },
        adSupported: { value: 0, total: 0 },
        midTier: { value: 0, total: 0 }
    };

    const series2 = {
        name: 'THIS IS SERIES TWO!',
        collection: { value: 32, total: 32 },
        active: { value: 22, total: 22 },
        passive: { value: 12, total: 12 },
        unknown: { value: 6, total: 6 },
        subscription: { value: 0, total: 0 },
        adSupported: { value: 0, total: 0 },
        midTier: { value: 0, total: 0 }
    };

    const series3 = {
        name: 'THIS IS SERIES THREE!',
        collection: { value: 32, total: 0 },
        active: { value: 22, total: 0 },
        passive: { value: 12, total: 0 },
        unknown: { value: 7, total: 0 },
        subscription: { value: 0, total: 10 },
        adSupported: { value: 0, total: 10 },
        midTier: { value: 0, total: 10 }
    };

    const renderMocked = (props: Partial<Props> = {}, container?: RenderResult) => {
        if (container) {
            container.rerender(<SourceOfStreamsChart {...{ ...defaultProps, ...props }} />);
            return container;
        }
        return render(<SourceOfStreamsChart {...{ ...defaultProps, ...props }} />);
    };

    test('renders series', () => {
        const { container } = renderMocked({ series: [series1, series2] });

        const barSeries1 = container.getElementsByClassName('highcharts-series-0').item(0);
        const barSeries2 = container.getElementsByClassName('highcharts-series-1').item(0);

        expect(barSeries1).toBeVisible();
        expect(barSeries2).toBeVisible();
    });

    test('renders data labels', () => {
        const series = [series1, series2];
        const container = renderMocked({ series });

        series.forEach(item =>
            [item.collection, item.active, item.passive, item.unknown].forEach(({ value }) => {
                const dataLabel = container.getByText(`${formatNumber(value)} ${formatMessage('comparison.streams')}`);
                expect(dataLabel).toBeVisible();
            }));
    });

    test('renders noData data labels', () => {
        const series = [series3];
        const container = renderMocked({ series });

        const dataLabel = container.getAllByText(formatMessage('error.noData.message'));
        expect(dataLabel.length).toBe(4);
    });

    test('renders help icons', () => {
        const { container } = renderMocked({ series: [series1, series2] });

        const helpIcons = container.getElementsByClassName('frc-help-icon');
        expect(helpIcons.length).toEqual(4);
    });

    test('help icons show tooltips when hovered', async () => {
        const { container, baseElement } = renderMocked({ series: [series1, series2] });

        const helpIcons = container.getElementsByClassName('frc-help-icon');

        fireEvent.mouseOver(helpIcons[0]);
        const collection = await waitForElement(
            () => getByText(baseElement, 'sourceOfStreams.tooltip.collection'),
            { container }
        );
        expect(collection).toBeVisible();

        fireEvent.mouseOver(helpIcons[1]);
        const active = await waitForElement(
            () => getByText(baseElement, 'sourceOfStreams.tooltip.active'),
            { container }
        );
        expect(active).toBeVisible();

        fireEvent.mouseOver(helpIcons[2]);
        const passive = await waitForElement(
            () => getByText(baseElement, 'sourceOfStreams.tooltip.passive'),
            { container }
        );
        expect(passive).toBeVisible();

        fireEvent.mouseOver(helpIcons[3]);
        const unknown = await waitForElement(
            () => getByText(baseElement, 'sourceOfStreams.tooltip.unknown'),
            { container }
        );
        expect(unknown).toBeVisible();
    });
    test('shows 100% when streams have no data', () => {
        const series = [series3];
        const container = renderMocked({ series });

        const percentLabel = container.getByText('100%');
        expect(percentLabel).toBeVisible();
    });
});

describe('<SourceOfStreamsChart>', () => {
    test('height is set according to number of elements', () => {
        const EMPTY = { value: 0, total: 0 };
        const series = { active: EMPTY, passive: EMPTY, collection: EMPTY, unknown: EMPTY, adSupported: EMPTY, subscription: EMPTY, midTier: EMPTY };
        expect((createChartOptions([series]).chart || {}).height).toBe(250);
        expect((createChartOptions([series, series, series, series]).chart || {}).height).toBe(400);
    });
});
