import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { h } from '../../../../base/browser/dom.js';
import { KeybindingLabel, unthemedKeybindingLabelOptions } from '../../../../base/browser/ui/keybindingLabel/keybindingLabel.js';
import { Separator } from '../../../../base/common/actions.js';
import { equals } from '../../../../base/common/arrays.js';
import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';
import { derived } from '../../../../base/common/observableInternal/derived.js';
import { autorun, autorunWithStore } from '../../../../base/common/observableInternal/autorun.js';
import { observableFromEvent } from '../../../../base/common/observableInternal/utils.js';
import '../../../../base/common/cancellation.js';
import { OS } from '../../../../base/common/platform.js';
import './inlineEditHintsWidget.css.js';
import { ContentWidgetPositionPreference } from '../../../browser/editorBrowser.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { Position } from '../../../common/core/position.js';
import { PositionAffinity } from '../../../common/model.js';
import { MenuEntryActionViewItem, createAndFillInActionBarActions } from '../../../../platform/actions/browser/menuEntryActionViewItem.js';
import { WorkbenchToolBar } from '../../../../platform/actions/browser/toolbar.js';
import { MenuId, MenuItemAction } from '../../../../platform/actions/common/actions.js';
import { IMenuService } from '../../../../platform/actions/common/actions.service.js';
import { ICommandService } from '../../../../platform/commands/common/commands.service.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.service.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.service.js';
var InlineEditHintsContentWidget_1;
let InlineEditHintsWidget = class InlineEditHintsWidget extends Disposable {
    constructor(editor, model, instantiationService) {
        super();
        this.editor = editor;
        this.model = model;
        this.instantiationService = instantiationService;
        this.alwaysShowToolbar = observableFromEvent(this, this.editor.onDidChangeConfiguration, () => this.editor.getOption(EditorOption.inlineEdit).showToolbar === 'always');
        this.sessionPosition = undefined;
        this.position = derived(this, reader => {
            const ghostText = this.model.read(reader)?.widget.model.ghostText.read(reader);
            if (!this.alwaysShowToolbar.read(reader) || !ghostText || ghostText.parts.length === 0) {
                this.sessionPosition = undefined;
                return null;
            }
            const firstColumn = ghostText.parts[0].column;
            if (this.sessionPosition && this.sessionPosition.lineNumber !== ghostText.lineNumber) {
                this.sessionPosition = undefined;
            }
            const position = ( new Position(
                ghostText.lineNumber,
                Math.min(firstColumn, this.sessionPosition?.column ?? Number.MAX_SAFE_INTEGER)
            ));
            this.sessionPosition = position;
            return position;
        });
        this._register(autorunWithStore((reader, store) => {
            const model = this.model.read(reader);
            if (!model || !this.alwaysShowToolbar.read(reader)) {
                return;
            }
            const contentWidget = store.add(this.instantiationService.createInstance(InlineEditHintsContentWidget, this.editor, true, this.position));
            editor.addContentWidget(contentWidget);
            store.add(toDisposable(() => editor.removeContentWidget(contentWidget)));
        }));
    }
};
InlineEditHintsWidget = ( __decorate([
    ( __param(2, IInstantiationService))
], InlineEditHintsWidget));
let InlineEditHintsContentWidget = class InlineEditHintsContentWidget extends Disposable {
    static { InlineEditHintsContentWidget_1 = this; }
    static { this._dropDownVisible = false; }
    static get dropDownVisible() { return this._dropDownVisible; }
    static { this.id = 0; }
    constructor(editor, withBorder, _position, instantiationService, _contextKeyService, _menuService) {
        super();
        this.editor = editor;
        this.withBorder = withBorder;
        this._position = _position;
        this._contextKeyService = _contextKeyService;
        this._menuService = _menuService;
        this.id = `InlineEditHintsContentWidget${InlineEditHintsContentWidget_1.id++}`;
        this.allowEditorOverflow = true;
        this.suppressMouseDown = false;
        this.nodes = h('div.inlineEditHints', { className: this.withBorder ? '.withBorder' : '' }, [
            h('div@toolBar'),
        ]);
        this.inlineCompletionsActionsMenus = this._register(this._menuService.createMenu(MenuId.InlineEditActions, this._contextKeyService));
        this.toolBar = this._register(instantiationService.createInstance(CustomizedMenuWorkbenchToolBar, this.nodes.toolBar, this.editor, MenuId.InlineEditToolbar, {
            menuOptions: { renderShortTitle: true },
            toolbarOptions: { primaryGroup: g => g.startsWith('primary') },
            actionViewItemProvider: (action, options) => {
                if (action instanceof MenuItemAction) {
                    return instantiationService.createInstance(StatusBarViewItem, action, undefined);
                }
                return undefined;
            },
            telemetrySource: 'InlineEditToolbar',
        }));
        this._register(this.toolBar.onDidChangeDropdownVisibility(e => {
            InlineEditHintsContentWidget_1._dropDownVisible = e;
        }));
        this._register(autorun(reader => {
            this._position.read(reader);
            this.editor.layoutContentWidget(this);
        }));
        this._register(autorun(reader => {
            const extraActions = [];
            for (const [_, group] of this.inlineCompletionsActionsMenus.getActions()) {
                for (const action of group) {
                    if (action instanceof MenuItemAction) {
                        extraActions.push(action);
                    }
                }
            }
            if (extraActions.length > 0) {
                extraActions.unshift(( new Separator()));
            }
            this.toolBar.setAdditionalSecondaryActions(extraActions);
        }));
    }
    getId() { return this.id; }
    getDomNode() {
        return this.nodes.root;
    }
    getPosition() {
        return {
            position: this._position.get(),
            preference: [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW],
            positionAffinity: PositionAffinity.LeftOfInjectedText,
        };
    }
};
InlineEditHintsContentWidget = InlineEditHintsContentWidget_1 = ( __decorate([
    ( __param(3, IInstantiationService)),
    ( __param(4, IContextKeyService)),
    ( __param(5, IMenuService))
], InlineEditHintsContentWidget));
class StatusBarViewItem extends MenuEntryActionViewItem {
    updateLabel() {
        const kb = this._keybindingService.lookupKeybinding(this._action.id, this._contextKeyService);
        if (!kb) {
            return super.updateLabel();
        }
        if (this.label) {
            const div = h('div.keybinding').root;
            const k = this._register(( new KeybindingLabel(div, OS, { disableTitle: true, ...unthemedKeybindingLabelOptions })));
            k.set(kb);
            this.label.textContent = this._action.label;
            this.label.appendChild(div);
            this.label.classList.add('inlineEditStatusBarItemLabel');
        }
    }
    updateTooltip() {
    }
}
let CustomizedMenuWorkbenchToolBar = class CustomizedMenuWorkbenchToolBar extends WorkbenchToolBar {
    constructor(container, editor, menuId, options2, menuService, contextKeyService, contextMenuService, keybindingService, commandService, telemetryService) {
        super(container, { resetMenu: menuId, ...options2 }, menuService, contextKeyService, contextMenuService, keybindingService, commandService, telemetryService);
        this.editor = editor;
        this.menuId = menuId;
        this.options2 = options2;
        this.menuService = menuService;
        this.contextKeyService = contextKeyService;
        this.menu = this._store.add(this.menuService.createMenu(this.menuId, this.contextKeyService, { emitEventsForSubmenuChanges: true }));
        this.additionalActions = [];
        this.prependedPrimaryActions = [];
        this._store.add(this.menu.onDidChange(() => this.updateToolbar()));
        this._store.add(this.editor.onDidChangeCursorPosition(() => this.updateToolbar()));
        this.updateToolbar();
    }
    updateToolbar() {
        const primary = [];
        const secondary = [];
        createAndFillInActionBarActions(this.menu, this.options2?.menuOptions, { primary, secondary }, this.options2?.toolbarOptions?.primaryGroup, this.options2?.toolbarOptions?.shouldInlineSubmenu, this.options2?.toolbarOptions?.useSeparatorsInPrimaryActions);
        secondary.push(...this.additionalActions);
        primary.unshift(...this.prependedPrimaryActions);
        this.setActions(primary, secondary);
    }
    setPrependedPrimaryActions(actions) {
        if (equals(this.prependedPrimaryActions, actions, (a, b) => a === b)) {
            return;
        }
        this.prependedPrimaryActions = actions;
        this.updateToolbar();
    }
    setAdditionalSecondaryActions(actions) {
        if (equals(this.additionalActions, actions, (a, b) => a === b)) {
            return;
        }
        this.additionalActions = actions;
        this.updateToolbar();
    }
};
CustomizedMenuWorkbenchToolBar = ( __decorate([
    ( __param(4, IMenuService)),
    ( __param(5, IContextKeyService)),
    ( __param(6, IContextMenuService)),
    ( __param(7, IKeybindingService)),
    ( __param(8, ICommandService)),
    ( __param(9, ITelemetryService))
], CustomizedMenuWorkbenchToolBar));
export { CustomizedMenuWorkbenchToolBar, InlineEditHintsContentWidget, InlineEditHintsWidget };
