import React from 'react';
import { render } from '@testing-library/react';
import { ToastProvider } from '@theorchard/suite-components';
import { IdentityContext } from '@theorchard/suite-identity';
import { MemoryRouter } from 'react-router-dom';
import { mockContext } from '../../../__mocks__';
import * as appContext from '../../../app/appContext';
import * as featuresQuery from '../../../queries/features/useFeaturesQuery';
import { MainContent } from '../mainContent';

vi.mock('@theorchard/suite-config', () => ({
    useAppConfig: () => mockContext.config,
}));

describe('<MainContent>', () => {
    const className = 'Test';
    const scrollTo = vi.fn();

    const renderComponent = (props: React.ComponentProps<typeof MainContent>, pathname = '/') =>
        render(<MainContent className={className} {...props} />, {
            wrapper: ({ children }) => (
                <ToastProvider>
                    <IdentityContext.Provider value={{ identity: mockContext.identity }}>
                        <MemoryRouter initialEntries={[{ pathname }]}>{children}</MemoryRouter>
                    </IdentityContext.Provider>
                </ToastProvider>
            ),
        });

    beforeEach(() => {
        scrollTo.mockClear();
        const mockMain = document.createElement('main');

        vi.spyOn(appContext, 'useAppContext').mockImplementation(() => mockContext);

        vi.spyOn(featuresQuery, 'useFeaturesQuery').mockReturnValue({
            loading: false,
            data: {},
        });

        vi.spyOn(React, 'useRef').mockReturnValue({
            current: {
                get: () => ({
                    ...mockMain,
                    scrollTo,
                }),
                set: () => {
                    /*noop*/
                },
            },
        });
    });

    afterEach(() => {
        vi.restoreAllMocks();
    });

    test('renders default component', () => {
        const { container } = renderComponent({ routes: [] });

        expect(container.querySelector(`.${className}`)).toBeVisible();
    });

    test('does not scroll to the top when re-rendered', () => {
        const { rerender } = renderComponent({ routes: [] });
        rerender(<MainContent className={className} routes={[]} />);
        expect(scrollTo).toHaveBeenCalledTimes(0);
    });

    describe('on "/account" route', () => {
        const path = '/account';

        test('renders account page when employee', () => {
            vi.spyOn(appContext, 'useAppContext').mockImplementation(() => ({
                ...mockContext,
                identity: {
                    ...mockContext.identity,
                    isEmployee: true,
                },
            }));
            const { getByText } = renderComponent({ routes: [] }, path);

            expect(getByText('First Name')).toBeVisible();
            expect(getByText('Mike')).toBeVisible();
            expect(getByText('Patton')).toBeVisible();
        });

        test('renders 404 page when not employee', () => {
            const { queryByText, getByText } = renderComponent({ routes: [] }, path);

            expect(queryByText('First Name')).toBeNull();
            expect(getByText('Oops! We lost this page.')).toBeVisible();
        });
    });
});
