
import { KeyMod as KeyMod$1, KeyCode } from '../../../../../base/common/keyCodes.js';
import { asyncTransaction, transaction } from '../../../../../base/common/observableInternal/base.js';
import '../../../../../base/common/arrays.js';
import '../../../../../base/common/event.js';
import '../../../../../base/common/lifecycle.js';
import '../../../../../base/common/observableInternal/autorun.js';
import '../../../../../base/common/observableInternal/derived.js';
import '../../../../../base/common/cancellation.js';
import '../../../../../base/common/observableInternal/utils.js';
import { splitLines } from '../../../../../base/common/strings.js';
import { localize2, localize } from '../../../../../nls.js';
import { MenuId, Action2 } from '../../../../../platform/actions/common/actions.js';
import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.service.js';
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.service.js';
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js';
import { EditorAction, EditorCommand } from '../../../../browser/editorExtensions.js';
import { EditorContextKeys } from '../../../../common/editorContextKeys.js';
import { Context } from '../../../suggest/browser/suggest.js';
import { showNextInlineSuggestionActionId, showPreviousInlineSuggestionActionId, inlineSuggestCommitId } from './commandIds.js';
import { InlineCompletionContextKeys } from './inlineCompletionContextKeys.js';
import { InlineCompletionsController } from './inlineCompletionsController.js';
import '../../../../../platform/notification/common/notification.js';
import { INotificationService } from '../../../../../platform/notification/common/notification.service.js';
import Severity$1 from '../../../../../base/common/severity.js';

class ShowNextInlineSuggestionAction extends EditorAction {
    static { this.ID = showNextInlineSuggestionActionId; }
    constructor() {
        super({
            id: ShowNextInlineSuggestionAction.ID,
            label: ( localize2(1186, "Show Next Inline Suggestion")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                InlineCompletionContextKeys.inlineSuggestionVisible
            )),
            kbOpts: {
                weight: 100,
                primary: KeyMod$1.Alt | KeyCode.BracketRight,
            },
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        controller?.model.get()?.next();
    }
}
class ShowPreviousInlineSuggestionAction extends EditorAction {
    static { this.ID = showPreviousInlineSuggestionActionId; }
    constructor() {
        super({
            id: ShowPreviousInlineSuggestionAction.ID,
            label: ( localize2(1187, "Show Previous Inline Suggestion")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                InlineCompletionContextKeys.inlineSuggestionVisible
            )),
            kbOpts: {
                weight: 100,
                primary: KeyMod$1.Alt | KeyCode.BracketLeft,
            },
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        controller?.model.get()?.previous();
    }
}
class TriggerInlineSuggestionAction extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.trigger',
            label: ( localize2(1188, "Trigger Inline Suggestion")),
            precondition: EditorContextKeys.writable
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        await asyncTransaction(async (tx) => {
            await controller?.model.get()?.triggerExplicitly(tx);
            controller?.playAccessibilitySignal(tx);
        });
    }
}
class ExplicitTriggerInlineEditAction extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.triggerInlineEditExplicit',
            label: ( localize2(1189, "Trigger Inline Edit")),
            precondition: EditorContextKeys.writable,
        });
    }
    async run(accessor, editor) {
        const notificationService = accessor.get(INotificationService);
        const controller = InlineCompletionsController.get(editor);
        await controller?.model.get()?.triggerExplicitly(undefined, true);
        if (!controller?.model.get()?.inlineEditAvailable.get()) {
            notificationService.notify({
                severity: Severity$1.Info,
                message: ( localize(1190, "No inline edit is available."))
            });
        }
    }
}
class TriggerInlineEditAction extends EditorCommand {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.triggerInlineEdit',
            precondition: EditorContextKeys.writable,
        });
    }
    async runEditorCommand(accessor, editor, args) {
        const controller = InlineCompletionsController.get(editor);
        await controller?.model.get()?.trigger(undefined, true);
    }
}
class AcceptNextWordOfInlineCompletion extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.acceptNextWord',
            label: ( localize2(1191, "Accept Next Word Of Inline Suggestion")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                InlineCompletionContextKeys.inlineSuggestionVisible
            )),
            kbOpts: {
                weight: KeybindingWeight.EditorContrib + 1,
                primary: KeyMod$1.CtrlCmd | KeyCode.RightArrow,
                kbExpr: ( ContextKeyExpr.and(
                    EditorContextKeys.writable,
                    InlineCompletionContextKeys.inlineSuggestionVisible
                )),
            },
            menuOpts: [{
                    menuId: MenuId.InlineSuggestionToolbar,
                    title: ( localize(1192, 'Accept Word')),
                    group: 'primary',
                    order: 2,
                }],
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        await controller?.model.get()?.acceptNextWord(controller.editor);
    }
}
class AcceptNextLineOfInlineCompletion extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.acceptNextLine',
            label: ( localize2(1193, "Accept Next Line Of Inline Suggestion")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                InlineCompletionContextKeys.inlineSuggestionVisible
            )),
            kbOpts: {
                weight: KeybindingWeight.EditorContrib + 1,
            },
            menuOpts: [{
                    menuId: MenuId.InlineSuggestionToolbar,
                    title: ( localize(1194, 'Accept Line')),
                    group: 'secondary',
                    order: 2,
                }],
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        await controller?.model.get()?.acceptNextLine(controller.editor);
    }
}
class AcceptInlineCompletion extends EditorAction {
    constructor() {
        super({
            id: inlineSuggestCommitId,
            label: ( localize2(1195, "Accept Inline Suggestion")),
            precondition: ( ContextKeyExpr.or(
                InlineCompletionContextKeys.inlineSuggestionVisible,
                InlineCompletionContextKeys.inlineEditVisible
            )),
            menuOpts: [{
                    menuId: MenuId.InlineSuggestionToolbar,
                    title: ( localize(1196, "Accept")),
                    group: 'primary',
                    order: 2,
                }, {
                    menuId: MenuId.InlineEditsActions,
                    title: ( localize(1196, "Accept")),
                    group: 'primary',
                    order: 2,
                }],
            kbOpts: [
                {
                    primary: KeyCode.Tab,
                    weight: 200,
                    kbExpr: ( ContextKeyExpr.or(( ContextKeyExpr.and(InlineCompletionContextKeys.inlineSuggestionVisible, ( EditorContextKeys.tabMovesFocus.toNegated()), ( Context.Visible.toNegated()), ( EditorContextKeys.hoverFocused.toNegated()), InlineCompletionContextKeys.inlineSuggestionHasIndentationLessThanTabSize)), ( ContextKeyExpr.and(InlineCompletionContextKeys.inlineEditVisible, ( EditorContextKeys.tabMovesFocus.toNegated()), ( Context.Visible.toNegated()), ( EditorContextKeys.hoverFocused.toNegated()), InlineCompletionContextKeys.tabShouldAcceptInlineEdit)))),
                }
            ],
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        if (controller) {
            controller.model.get()?.accept(controller.editor);
            controller.editor.focus();
        }
    }
}
class JumpToNextInlineEdit extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.jump',
            label: ( localize2(1197, "Jump to next inline edit")),
            precondition: InlineCompletionContextKeys.inlineEditVisible,
            menuOpts: [{
                    menuId: MenuId.InlineEditsActions,
                    title: ( localize(1198, "Jump")),
                    group: 'primary',
                    order: 1,
                    when: ( InlineCompletionContextKeys.cursorAtInlineEdit.toNegated()),
                }],
            kbOpts: {
                primary: KeyCode.Tab,
                weight: 201,
                kbExpr: ( ContextKeyExpr.and(InlineCompletionContextKeys.inlineEditVisible, ( EditorContextKeys.tabMovesFocus.toNegated()), ( Context.Visible.toNegated()), ( EditorContextKeys.hoverFocused.toNegated()), InlineCompletionContextKeys.tabShouldJumpToInlineEdit)),
            }
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        if (controller) {
            controller.jump();
        }
    }
}
class HideInlineCompletion extends EditorAction {
    static { this.ID = 'editor.action.inlineSuggest.hide'; }
    constructor() {
        super({
            id: HideInlineCompletion.ID,
            label: ( localize2(1199, "Hide Inline Suggestion")),
            precondition: ( ContextKeyExpr.or(
                InlineCompletionContextKeys.inlineSuggestionVisible,
                InlineCompletionContextKeys.inlineEditVisible
            )),
            kbOpts: {
                weight: 100,
                primary: KeyCode.Escape,
            },
            menuOpts: [{
                    menuId: MenuId.InlineEditsActions,
                    title: ( localize(1200, "Reject")),
                    group: 'primary',
                    order: 3,
                }]
        });
    }
    async run(accessor, editor) {
        const controller = InlineCompletionsController.get(editor);
        transaction(tx => {
            controller?.model.get()?.stop('explicitCancel', tx);
        });
    }
}
class ToggleAlwaysShowInlineSuggestionToolbar extends Action2 {
    static { this.ID = 'editor.action.inlineSuggest.toggleAlwaysShowToolbar'; }
    constructor() {
        super({
            id: ToggleAlwaysShowInlineSuggestionToolbar.ID,
            title: ( localize(1201, "Always Show Toolbar")),
            f1: false,
            precondition: undefined,
            menu: [{
                    id: MenuId.InlineSuggestionToolbar,
                    group: 'secondary',
                    order: 10,
                }],
            toggled: ( ContextKeyExpr.equals('config.editor.inlineSuggest.showToolbar', 'always'))
        });
    }
    async run(accessor) {
        const configService = accessor.get(IConfigurationService);
        const currentValue = configService.getValue('editor.inlineSuggest.showToolbar');
        const newValue = currentValue === 'always' ? 'onHover' : 'always';
        configService.updateValue('editor.inlineSuggest.showToolbar', newValue);
    }
}
class DevExtractReproSample extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.inlineSuggest.dev.extractRepro',
            label: ( localize(1202, "Developer: Extract Inline Suggest State")),
            alias: 'Developer: Inline Suggest Extract Repro',
            precondition: InlineCompletionContextKeys.inlineEditVisible,
        });
    }
    async run(accessor, editor) {
        const clipboardService = accessor.get(IClipboardService);
        const controller = InlineCompletionsController.get(editor);
        const m = controller?.model.get();
        if (!m) {
            return;
        }
        const repro = m.extractReproSample();
        const inlineCompletionLines = splitLines(JSON.stringify({ inlineCompletion: repro.inlineCompletion }, null, 4));
        const json = ( inlineCompletionLines.map(l => '// ' + l)).join('\n');
        const reproStr = `${repro.documentValue}\n\n// <json>\n${json}\n// </json>\n`;
        await clipboardService.writeText(reproStr);
        return { reproCase: reproStr };
    }
}

export { AcceptInlineCompletion, AcceptNextLineOfInlineCompletion, AcceptNextWordOfInlineCompletion, DevExtractReproSample, ExplicitTriggerInlineEditAction, HideInlineCompletion, JumpToNextInlineEdit, ShowNextInlineSuggestionAction, ShowPreviousInlineSuggestionAction, ToggleAlwaysShowInlineSuggestionToolbar, TriggerInlineEditAction, TriggerInlineSuggestionAction };
