import React from 'react';
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
import { AuthClientContext } from '@theorchard/suite-auth';
import { ToastProvider } from '@theorchard/suite-components';
import { IdentityContext } from '@theorchard/suite-identity';
import { ThemeProvider } from '@theorchard/suite-theming';
import { AppDataProvider } from './appContext';
import type { SuiteInitContext } from '../types';
import type { NormalizedCacheObject } from '@apollo/client';

let dummyApolloClient: ApolloClient<NormalizedCacheObject> | undefined;
const getDummyClient = () => {
    if (!dummyApolloClient) dummyApolloClient = new ApolloClient({ cache: new InMemoryCache() });
    return dummyApolloClient;
};

interface SuiteAppProvidersProps<AppData> {
    children?: React.ReactNode;
    context: SuiteInitContext<AppData>;
}

export function SuiteAppProviders<AppData>({ children, context }: SuiteAppProvidersProps<AppData>) {
    const { graphqlClient, authClient, identity, config, appData, sessionExpired } = context;

    return (
        <AppDataProvider value={appData}>
            <AuthClientContext.Provider value={{ authClient, sessionExpired }}>
                <ApolloProvider client={graphqlClient ?? getDummyClient()}>
                    <IdentityContext.Provider value={{ identity }}>
                        <ThemeProvider config={config}>
                            <ToastProvider>{children}</ToastProvider>
                        </ThemeProvider>
                    </IdentityContext.Provider>
                </ApolloProvider>
            </AuthClientContext.Provider>
        </AppDataProvider>
    );
}
