import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { input, forwardRef, Component, Input } from '@angular/core';
import * as i2 from '@angular/forms';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { filter } from 'rxjs/operators';
import { format } from 'sql-formatter';
import { NgmBaseEditorDirective } from '@metad/ocap-angular/formula';
import * as i3 from 'ngx-monaco-editor';
import { MonacoEditorModule } from 'ngx-monaco-editor';
import { nonNullable } from '@metad/ocap-core';
import { isNil, lowerCase, isEmpty } from 'lodash-es';

function createTableSuggestions(model, position, entitySets) {
    const word = model.getWordUntilPosition(position);
    let from = null;
    let startColumn = word.startColumn;
    while (!from?.word && startColumn > 0) {
        from = model.getWordUntilPosition(new monaco.Position(position.lineNumber, --startColumn));
    }
    if (!isNil(from?.word) && lowerCase(from.word) === 'from') {
        const range = {
            startLineNumber: position.lineNumber,
            endLineNumber: position.lineNumber,
            // startColumn: word.startColumn,
            // endColumn: word.endColumn,
            startColumn: word.startColumn,
            endColumn: word.endColumn + 1,
        };
        return entitySets?.map(entity => ({
            label: entity.name,
            kind: monaco.languages.CompletionItemKind.Method,
            detail: entity.name,
            insertText: entity.name,
            range: range,
        }));
    }
    return null;
}
function createFieldSuggestions(range, entitySets) {
    const proposals = [];
    proposals.push({
        label: ``,
        kind: monaco.languages.CompletionItemKind.Method,
        detail: ``,
        insertText: ``,
        range: range,
    });
    entitySets?.forEach(entity => proposals.push({
        label: entity.name,
        kind: monaco.languages.CompletionItemKind.Method,
        detail: ``,
        insertText: entity.name,
        range: range,
    }));
    return proposals;
}
const createInfoProvider = (entitySets) => {
    return {
        triggerCharacters: [' ', '.', 'abcd'],
        provideCompletionItems: (model, position) => {
            const suggestions = createTableSuggestions(model, position, entitySets);
            if (!isEmpty(suggestions)) {
                return {
                    suggestions
                };
            }
            const word = model.getWordUntilPosition(position);
            const range = {
                startLineNumber: position.lineNumber,
                endLineNumber: position.lineNumber,
                // startColumn: word.startColumn,
                // endColumn: word.endColumn,
                startColumn: word.startColumn,
                endColumn: word.endColumn,
            };
            return {
                suggestions: createFieldSuggestions(range, entitySets),
            };
        },
    };
};

// @ts-nocheck
class NgmSQLEditorComponent extends NgmBaseEditorDirective {
    constructor() {
        super(...arguments);
        this.entityType = input();
        this._entitySets$ = new BehaviorSubject(null);
        this.languageId = 'sql';
    }
    // EntityType
    get entitySets() {
        return this._entitySets$.value;
    }
    set entitySets(value) {
        this._entitySets$.next(value);
    }
    ngOnInit() {
        // 要使用 `monaco.languages.` 进行调用, 不能使用 `languages.`
        combineLatest([
            this.editor$.pipe(filter(nonNullable)),
            this._entitySets$,
            // this._entityType$.pipe(filter(nonNullable))
        ]).subscribe(([editor, entitySets]) => {
            this.dispose();
            // define a document formatting provider
            // then you contextmenu will add an "Format Document" action
            this._providers.push(monaco.languages.registerDocumentFormattingEditProvider(this.languageId, {
                provideDocumentFormattingEdits(model, options) {
                    const formatted = format(model.getValue(), {
                        indent: ' '.repeat(options.tabSize)
                    });
                    return [
                        {
                            range: model.getFullModelRange(),
                            text: formatted
                        }
                    ];
                }
            }));
            // define a range formatting provider
            // select some codes and right click those codes
            // you contextmenu will have an "Format Selection" action
            this._providers.push(monaco.languages.registerDocumentRangeFormattingEditProvider(this.languageId, {
                provideDocumentRangeFormattingEdits(model, range, options) {
                    const formatted = format(model.getValueInRange(range), {
                        indent: ' '.repeat(options.tabSize)
                    });
                    return [
                        {
                            range: range,
                            text: formatted
                        }
                    ];
                }
            }));
            if (entitySets) {
                this._providers.push(monaco.languages.registerCompletionItemProvider(this.languageId, createInfoProvider(entitySets)));
            }
            // this._providers.push(monaco.languages.registerCompletionItemProvider(this.languageId, createHierarchyProvider(entityType)))
            // this._providers.push(monaco.languages.registerCompletionItemProvider(this.languageId, createSuffixProvider(entityType)))
            // this._providers.push(monaco.languages.registerSignatureHelpProvider(this.languageId, createSignatureHelpProvider()))
            // this._providers.push(monaco.languages.registerHoverProvider(this.languageId, createHoverProvider(entityType)))
            // this._providers.push(
            //   monaco.languages.registerDocumentSemanticTokensProvider('plaintext', createDocumentSemanticTokensProvider(entityType))
            // )
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgmSQLEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.12", type: NgmSQLEditorComponent, isStandalone: true, selector: "ngm-sql-editor", inputs: { entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, entitySets: { classPropertyName: "entitySets", publicName: "entitySets", isSignal: false, isRequired: false, transformFunction: null } }, host: { classAttribute: "ngm-sql-editor" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                multi: true,
                useExisting: forwardRef(() => NgmSQLEditorComponent)
            },
            {
                provide: NgmBaseEditorDirective,
                useExisting: NgmSQLEditorComponent
            }
        ], usesInheritance: true, ngImport: i0, template: "<ngx-monaco-editor [ngStyle]=\"{'height': 'calc(100% - 1rem)'}\"\n    [options]=\"editorOptions()\"\n    [(ngModel)]=\"code\"\n    (ngModelChange)=\"onModelChange($event)\"\n    (resized)=\"onResized($event)\"\n    (onInit)=\"onInit($event)\"\n></ngx-monaco-editor>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MonacoEditorModule }, { kind: "component", type: i3.EditorComponent, selector: "ngx-monaco-editor", inputs: ["options", "model"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgmSQLEditorComponent, decorators: [{
            type: Component,
            args: [{ standalone: true, imports: [CommonModule, FormsModule, MonacoEditorModule], selector: 'ngm-sql-editor', host: {
                        class: 'ngm-sql-editor'
                    }, providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            multi: true,
                            useExisting: forwardRef(() => NgmSQLEditorComponent)
                        },
                        {
                            provide: NgmBaseEditorDirective,
                            useExisting: NgmSQLEditorComponent
                        }
                    ], template: "<ngx-monaco-editor [ngStyle]=\"{'height': 'calc(100% - 1rem)'}\"\n    [options]=\"editorOptions()\"\n    [(ngModel)]=\"code\"\n    (ngModelChange)=\"onModelChange($event)\"\n    (resized)=\"onResized($event)\"\n    (onInit)=\"onInit($event)\"\n></ngx-monaco-editor>\n" }]
        }], propDecorators: { entitySets: [{
                type: Input
            }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { NgmSQLEditorComponent };
//# sourceMappingURL=metad-ocap-angular-sql.mjs.map
