import React from 'react';
import { SidebarPortal } from '@theorchard/suite-components';
import { BannersContainer } from '../components/bannersContainer';
import { MainContent } from '../components/mainContent';
import { MainNav } from '../components/mainNav';
import { PageIdleListener } from '../components/pageIdleListener';
import { SessionExpirationModal } from '../components/sessionExpirationModal';
import { FRAMEWORK_CLASS_NAME } from '../constants';
import Datadog from '../datadog';
import { FatalErrorPage, SplashPage } from '../pages';
import Segment from '../segment';
import { SuiteAppProviders } from './suiteAppProviders';
import { SuiteAppWrapper } from './suiteAppWrapper';
import { useSuiteApplication } from './useSuiteApplication';
import type { UseSuiteApplicationResult } from './useSuiteApplication';
import type { SuiteAppProps } from '../types';

function SuiteApplicationContent<AppData>({
    mainNav,
    routes,
    result,
    sessionExpiration,
}: SuiteAppProps<AppData> & { result: UseSuiteApplicationResult<AppData> }) {
    const {
        loading,
        error,
        data: { config, authClient, graphqlClient, identity },
    } = result;

    if (error) return <FatalErrorPage error={error} config={config} />;
    if (loading) return <SplashPage />;

    if (!authClient || !graphqlClient || !identity)
        return (
            <FatalErrorPage
                config={config}
                error={{
                    name: 'InitError',
                    message: 'Application not initialized',
                }}
            />
        );

    const showMainNav = mainNav !== false;

    return (
        <>
            {showMainNav && <BannersContainer />}

            <div className={`${FRAMEWORK_CLASS_NAME} SuiteApplication`}>
                {showMainNav && (
                    <MainNav {...(mainNav || {})} title={config.appTitle} loading={loading} />
                )}
                <SessionExpirationModal config={sessionExpiration}>
                    <MainContent routes={routes} />
                </SessionExpirationModal>
                <SidebarPortal />
            </div>
        </>
    );
}

const DEFAULT_SESSION_EXPIRATION = { modal: () => true };

export function SuiteApplication<AppData>(props: SuiteAppProps<AppData>) {
    const {
        apollo,
        idleTimeoutSeconds = 0,
        plugins,
        resourceTypeActions,
        sessionExpiration = DEFAULT_SESSION_EXPIRATION,
    } = props;
    const result = useSuiteApplication({
        plugins,
        apollo,
        resourceTypeActions,
        sessionExpiration,
    });

    return (
        <>
            <SuiteAppProviders context={result.data}>
                <SuiteAppWrapper {...result} plugins={plugins}>
                    <SuiteApplicationContent result={result} {...props} />
                </SuiteAppWrapper>
            </SuiteAppProviders>

            {idleTimeoutSeconds > 0 && (
                <PageIdleListener
                    timeoutSeconds={idleTimeoutSeconds}
                    onIdle={async () => {
                        const message = 'Session timed out';
                        const params = { idleTimeoutSeconds };
                        Datadog.addAction(message, params);
                        await Segment.trackEvent(message, params);
                        await result.data.authClient?.endSession('idle_timeout');
                    }}
                />
            )}
        </>
    );
}
