import * as ReactDOMClient from 'react-dom/client';
import * as services from 'src/services';
import { LocalizationManager } from 'src/utils';
import Datadog from 'src/utils/datadog';
import { initReactPhpApplications } from '../index';
import type { FeatureFlagDictionary } from '@orchard/frontend-identity';
import type { WorkstationUser } from 'src/types';

jest.mock('react-dom/client', () => ({
    createRoot: jest.fn(() => ({ render: jest.fn(), unmount: jest.fn() })),
}));

jest.mock('src/services', () => ({
    __esModule: true,
    ...jest.requireActual('src/services'),
}));

describe('initReactPhpApplications', () => {
    const config = {
        locales: { en: { term: 'test' }, de: { term: 'teste' } },
        locale: 'de',
    };
    const user = { identity: { id: '123' } } as WorkstationUser;

    beforeEach(() => {
        jest.mocked(ReactDOMClient.createRoot).mockClear();
        jest.spyOn(services, 'getUser').mockResolvedValue({
            user,
            featureFlags: {} as FeatureFlagDictionary,
        });
        jest.spyOn(LocalizationManager, 'registerTranslations');
        jest.spyOn(Datadog, 'init').mockImplementation();
        jest.spyOn(Datadog, 'setUser').mockImplementation();

        document.body.innerHTML = `
                <div id="react_header_app"></div>
                <div id="react_footer_app"></div>
            `;
    });

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

    test('renders two different apps', async () => {
        await initReactPhpApplications(null, config);

        expect(ReactDOMClient.createRoot).toHaveBeenCalledTimes(2);
    });

    test('calls Datadog.init', async () => {
        await initReactPhpApplications(null, config);

        expect(Datadog.init).toHaveBeenCalledTimes(1);
        expect(Datadog.init).toHaveBeenCalledWith();
    });

    test('calls Datadog.setUser', async () => {
        await initReactPhpApplications(null, config);

        expect(Datadog.setUser).toHaveBeenCalledTimes(1);
        expect(Datadog.setUser).toHaveBeenCalledWith(user.identity);
    });

    test('is assigned to window', () => {
        expect(window.initReactPhpApplications).toStrictEqual(
            initReactPhpApplications
        );
    });
});
