import React from 'react';
import { render } from '@testing-library/react';
import * as AppConfigModule from '@theorchard/suite-frontend';
import { mockAppConfig } from 'lib/test-helpers/factories';
import { MemoryRouter } from 'react-router-dom';
import {
    LAST_VENDOR_ID_BEFORE_ANALYTICS_DEPRECIATION,
    PERMITTED_VENDOR_IDS_AFTER_ANALYTICS_DEPRECIATION,
} from 'src/constants';
import { formatMessage } from 'src/utils';
import SplashScreen, { CLASSNAME_FOOTER } from '../splashScreen';

jest.mock('@orchard/frontend-react-components', () => ({
    ...jest.requireActual('@orchard/frontend-react-components'),
    InsightsIcon: () => <div data-testid="frc-insights-icon" />,
}));

jest.mock('@theorchard/suite-icons', () => ({
    ...jest.requireActual('@theorchard/suite-icons'),
    AppIcon: ({ app }: { app: string }) => (
        <div data-testid="suite-app-icon" data-app={app} />
    ),
}));

jest.mock('@theorchard/suite-frontend', () => ({
    __esModule: true,
    ...jest.requireActual('@theorchard/suite-frontend'),
}));

describe('SplashScreen', () => {
    const isSoSEnabled = (feature: string): boolean =>
        feature === 'Source of Stream';

    beforeEach(() => {
        jest.spyOn(AppConfigModule, 'useAppConfig').mockReturnValue(
            mockAppConfig
        );
    });

    const defaultProps = {
        identity: {
            vendorId: 1,
            hasFeatureControl: (feature: string) => isSoSEnabled(feature),
            hasFeatureFlag: () => true,
        },
    };

    const renderComponent = (props: Record<string, unknown> = {}) =>
        render(
            <MemoryRouter>
                <SplashScreen {...(defaultProps as any)} {...(props as any)} />
            </MemoryRouter>
        );

    const text = formatMessage('subheader.analytics.physicalReporting');

    test('renders footer', () => {
        const { container } = renderComponent();
        expect(
            container.querySelector(`.${CLASSNAME_FOOTER}`)
        ).toBeInTheDocument();
    });

    describe('with Feature "Workstation Physical Reporting"', () => {
        describe('when enabled', () => {
            test('renders Physical Reporting link', () => {
                const identity = {
                    hasFeatureControl: (feature: string) =>
                        feature === 'Workstation Physical Reporting' ||
                        isSoSEnabled(feature),
                    hasFeatureFlag: () => true,
                };
                const { getByText } = renderComponent({ identity });
                expect(getByText(text)).toHaveAttribute(
                    'href',
                    '/analytics/reporting/physical/report/product-view?utm_source=workstation&utm_medium=link&utm_campaign=SplashPhysicalReporting'
                );
            });
        });

        describe('when disabled', () => {
            test('does not render Physical Reporting link', () => {
                const identity = {
                    hasFeatureControl: (feature: string) =>
                        isSoSEnabled(feature),
                    hasFeatureFlag: () => true,
                };
                const { queryByText } = renderComponent({ identity });
                expect(queryByText(text)).toBeNull();
            });
        });
    });

    describe('redirection to Physical Reporting', () => {
        test('does not redirect by default', () => {
            const identity = {
                hasFeatureControl: jest
                    .fn()
                    .mockImplementation(
                        (feature: string) => feature === 'Source of Stream'
                    ),
                hasFeatureFlag: () => true,
                vendorId: 5,
            };

            const { container } = renderComponent({ identity });
            expect(
                container.querySelector('.SplashScreen-container')
            ).toBeInTheDocument();
        });

        test('redirects if source of streams is disabled', () => {
            const identity = {
                hasFeatureControl: jest.fn().mockReturnValueOnce(false),
                hasFeatureFlag: () => true,
                vendorId: 5,
            };

            const { container } = renderComponent({ identity });
            expect(
                container.querySelector('.SplashScreen-container')
            ).toBeNull();
        });

        test('redirects if user is newer than Insights launch', () => {
            const identity = {
                hasFeatureControl: jest.fn().mockReturnValueOnce(true),
                hasFeatureFlag: () => true,
                vendorId: LAST_VENDOR_ID_BEFORE_ANALYTICS_DEPRECIATION + 1,
            };

            const { container } = renderComponent({ identity });
            expect(
                container.querySelector('.SplashScreen-container')
            ).toBeNull();
        });

        test('does not redirect new user with permission', () => {
            const identity = {
                hasFeatureControl: jest.fn().mockReturnValueOnce(true),
                hasFeatureFlag: () => true,
                vendorId: PERMITTED_VENDOR_IDS_AFTER_ANALYTICS_DEPRECIATION[0],
            };

            const { container } = renderComponent({ identity });
            expect(
                container.querySelector('.SplashScreen-container')
            ).toBeInTheDocument();
        });
    });

    describe('Insights icon', () => {
        test('renders FRC InsightsIcon when the FF is OFF', () => {
            const identity = {
                hasFeatureControl: (feature: string) => isSoSEnabled(feature),
                hasFeatureFlag: () => false,
            };

            const { getByTestId, queryByTestId } = renderComponent({
                identity,
            });
            expect(getByTestId('frc-insights-icon')).toBeInTheDocument();
            expect(queryByTestId('suite-app-icon')).toBeNull();
        });

        test('renders Suite AppIcon when the FF is ON', () => {
            const identity = {
                hasFeatureControl: (feature: string) => isSoSEnabled(feature),
                hasFeatureFlag: () => true,
            };
            const { getByTestId, queryByTestId } = renderComponent({
                identity,
            });
            expect(getByTestId('suite-app-icon')).toBeInTheDocument();
            expect(getByTestId('suite-app-icon')).toHaveAttribute(
                'data-app',
                'insights'
            );
            expect(queryByTestId('frc-insights-icon')).toBeNull();
        });
    });
});
