import { concat, Observable, ReplaySubject, throwError, from, Subscribable, ObservableInput } from 'rxjs';
import { map } from 'rxjs/operators';
import { PlatformContext, createWebWorkerMessageTransports } from '@workbench-stack/extension-api';
import { ISettingsCascade } from '@workbench-stack/core';
// import ExtensionHostWorker from '../extensions/workers/main.worker';
import { LocalStorageSubject } from '../util/local-storage-subject';
import { ApolloClient, ApolloQueryResult } from 'apollo-client';
import gql from 'graphql-tag';
import { ViewerSettingsDocument } from '../components/generated-model';
import { logger } from '@cdm-logger/client';
import { Store } from 'redux';

// const worker = new Worker('../extensions/workers/main.worker', { type: 'module' });
/**
 * Creates the {@link PlatformContext} for the web app.
 */
export function createPlatformContext(client: ApolloClient<any>, reduxState$: Observable<any>, store?: Store<any>): PlatformContext {
    const updatedSettings = new ReplaySubject<ISettingsCascade>(1);
    const context: PlatformContext | any = {
        store,
        reduxState$,
        apolloClient: client,

        settings: from(client.watchQuery<ISettingsCascade>({
            query: ViewerSettingsDocument,
        })).pipe(map( ({ data }) => data)) as any,

        updateSettings: async (subject, edit) => {

        },

        queryGraphQL: (request, variables) => from<ObservableInput<any>>(client.watchQuery({
            query:
                gql`
                ${request}
                `,
            variables,
        })),

        createExtensionHost: () => {
            logger.info({'childName': 'PlatformContext'}, 'createExtensionHost');
            const worker = new Worker('../extensions/workers/main.worker', { type: 'module' });
            const messageTransports = createWebWorkerMessageTransports(worker);
            return new Observable(sub => {
                sub.next(messageTransports);
                return () => worker.terminate();
            });
        },

        getScriptURLForExtension: bundleURL => bundleURL,
        cdecodeURL: 'http://localhost:8085'/*(window.context as any).externalURL,*/,
        clientApplication: 'cdecode',
        traceExtensionHostCommunication: new LocalStorageSubject<boolean>('traceExtensionHostCommunication', false),
    };

    return context;
}
