import { from, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { IExtensionHostClientConnection } from '@workbench-stack/extension-api';
import { Connection } from '@workbench-stack/extension-api';
import { ClientConfiguration } from '../api/client/client-configuration';
import { ClientExtensions } from '../api/client/client-extensions';
import { ClientDocuments } from '../api/client/client-documents';
import { MainThreadDocumentsAndEditors } from '../api/client/client-document-and-editors';
import { ClientLanguageFeatures } from '../api/client/client-language-feature';
import { ClientCommands } from '../api/client/client-commads';
import { Services } from '../services/services';
import { ClientViews } from '../api/client/client-views';
import { ClientEditorWindows } from '../api/client/client-editor-windows';
import { ClientTreeViews } from '../api/client/client-tree-views';

export function createExtensionHostClientConnection(connection: Connection, services: Services): IExtensionHostClientConnection {
    const subscription = new Subscription();
    connection.onRequest('ping', () => 'pong');

    const windows = new ClientEditorWindows(connection, services.windows);

    const documentsAndEditors = new MainThreadDocumentsAndEditors(
        connection,
        services.modelService,
        services.codeEditorService,
        services.textFileService,
    );

    // subscription.add(new ClientExtensions(connection, services.extensions));
    subscription.add(windows);
    subscription.add(new ClientConfiguration(connection, services.configuration));
    subscription.add(new ClientViews(connection, services.views, services.textDocumentLocations));

    ///was commented
    // subscription.add(
    //     new ClientDocuments(
    //         connection,
    //         from(services.model.getModels()).pipe(
    //             map(
    //                 ({ visibleViewComponents }) =>
    //                     visibleViewComponents && visibleViewComponents.map(({ item }) => item),
    //             ),
    //             distinctUntilChanged(),
    //         ),
    //     ),
    // );
    //
    subscription.add(
        new ClientTreeViews(
            connection,
            services.treeViews,
        ),
    );

    subscription.add(
        new ClientLanguageFeatures(
            connection,
            services.textDocumentHover,
            services.textDocumentDefinition,
            services.textDocumentTypeDefinition,
            services.textDocumentImplementation,
            services.textDocumentReferences,
            services.textDocumentСompletion,
            services.textDocumentHightLight,
            services.textDocumentRename,
            services.textDocumentFormatting,
            services.textDocumentReferences,
            services.textDocumentSymbolDefinition,
            services.textDocumentCodeAction,
            services.textDocumentCodeLenth,
            services.textDocumentLink,
            services.textDocumentColor,
            services.textDocumentFoldingRanges,
            services.textDocumentWorkspaceSymbol,
            (services as any).rangeFormattingEditProviderRegistry,
        ),
    );

    subscription.add(new ClientCommands(connection, services.commands));
    subscription.add(new ClientExtensions(connection, services.extensions));

    return {
        setTracer: tracer => {
            connection.trace(tracer);
        },
        unsubscribe: () => subscription.unsubscribe(),
    };
}
