import { fromEventPattern } from 'rxjs';
import { IModelService } from '@workbench-stack/core';
import { URI } from '@vscode/monaco-editor/esm/vs/base/common/uri';
import { ITextModel, ITextBufferFactory, ITextModelCreationOptions } from '@vscode/monaco-editor/esm/vs/editor/common/model';
import { StaticServices } from '@vscode/monaco-editor/esm/vs/editor/standalone/browser/standaloneServices';
import { createModel } from '@vscode/monaco-editor/esm/vs/editor/standalone/browser/standaloneEditor';
import { IModelService as IEditorModelService } from '@vscode/monaco-editor/esm/vs/editor/common/services/modelService';
import { ILanguageSelection } from '@vscode/monaco-editor/esm/vs/editor/common/services/modeService';
import { flatMap } from 'rxjs/operators';
import { injectable } from 'inversify';


/**
 * Creates a {@link ModelService} instance.
 */
@injectable()
export class ModelService implements IModelService {
    public onModelAdded: any;
    public onModelRemoved: any;
    public onModelModeChanged: any;

    private static _modelService: IEditorModelService;
    constructor() {
        this.onModelAdded = fromEventPattern<ITextModel>(StaticServices.modelService.get().onModelAdded);
        this.onModelRemoved = fromEventPattern<ITextModel>(StaticServices.modelService.get().onModelRemoved);
        this.onModelModeChanged = fromEventPattern<{ model: ITextModel, oldModeId: string }>(StaticServices.modelService.get().onModelModeChanged);

        this.onModelAdded.subscribe(e => console.log('[check>>>]: model added', e.uri));
    }

    public static getModelService() {
        if (!this._modelService) {
            this._modelService = StaticServices.modelService.get();
        }
        return this._modelService;
    }

    public createModel(value: string | ITextBufferFactory, languageSelection: string | ILanguageSelection, resource: URI, isForSimpleWidget?: boolean) {
        let model: ITextModel;
        const service = ModelService.getModelService();
        if (service) {
            // console.warn('(ModelService Rewrite TODO), if modelService exist then refactor this code', service);
        }
        if (typeof languageSelection === 'string') {
            model = createModel(value as string, languageSelection, resource);
        } else {
            model = StaticServices.modelService.get().createModel(value, languageSelection, resource);
        }
        // console.log('[check>>>]: model created', model);
        return model;
    }

    public updateModel(model: ITextModel, value: string | ITextBufferFactory): void {
        return StaticServices.modelService.get().updateModel(model, value);
    }

    public setMode(model: ITextModel, languageSelection: ILanguageSelection): void {
        return StaticServices.modelService.get().setMode(model, languageSelection);
    }

    public getModel(uri: URI): ITextModel | null {
        return StaticServices.modelService.get().getModel(uri);
    }

    public getCreationOptions(language: string, resource: URI, isForSimpleWidget: boolean): ITextModelCreationOptions {
        return StaticServices.modelService.get().getCreationOptions(language, resource, isForSimpleWidget);
    }

    public getModels(): ITextModel[] {
        return StaticServices.modelService.get().getModels();
    }

    public destroyModel(resource: URI): void {
        return StaticServices.modelService.get().destroyModel(resource);
    }

}



// export function modelService(apolloClient: ApolloClient<any>, store$) {
//     return createModelService();
// }
