import React from 'react';
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { AppConfigContext, SuiteAppProviders } from '../../src';
import { createAppConfig, createAuthClient, createIdentity } from './mocks';
import type { SuiteInitContext } from '../../src';
import type { DeepPartial } from '../../src/types';
import type { RenderResult, RenderOptions } from '@testing-library/react';
export type { RenderResult };

export interface RenderInAppContext extends Omit<DeepPartial<SuiteInitContext>, 'identity'> {
    pathname?: string;
    search?: string;
    initialIndex?: number;
    identity?: DeepPartial<SuiteInitContext['identity']>;
    options?: Omit<RenderOptions, 'queries'>;
}

/**
 * Renders a component in the context of the Suite app, with the ability to
 * provide a custom config props and other initial context to mimic specific scenarios.
 *
 * This is essentially suite-testing's `renderInAppContext` function, renamed for clarity.
 *
 * At this point in the tooling (2025-05-01), it is probably worth deprecating
 * suite-testing altogether and incorporating all of it into suite-frontend.
 */
export const renderInAppContextLite = (
    component: React.ReactElement,
    context: RenderInAppContext = {}
): RenderResult => {
    const { pathname = '/', search, initialIndex, options, identity = {}, ...appContext } = context;
    const config = createAppConfig(appContext.config);

    const ContextTree: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
        <AppConfigContext.Provider value={{ config }}>
            <SuiteAppProviders
                context={{
                    ...appContext,
                    identity: createIdentity(identity),
                    authClient: createAuthClient(appContext.authClient),
                    config,
                }}
            >
                <MemoryRouter initialEntries={[{ pathname, search }]} initialIndex={initialIndex}>
                    {children}
                </MemoryRouter>
            </SuiteAppProviders>
        </AppConfigContext.Provider>
    );

    const renderResult = render(<ContextTree>{component}</ContextTree>, options);

    return {
        ...renderResult,
        rerender: (comp: React.ReactNode) => {
            renderResult.rerender(<ContextTree>{comp}</ContextTree>);
        },
    };
};
