import { Codicon } from '../../../../../base/common/codicons.js';
import { Disposable } from '../../../../../base/common/lifecycle.js';
import { ThemeIcon } from '../../../../../base/common/themables.js';
import { EditorAction2 } from '../../../../../editor/browser/editorExtensions.js';
import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js';
import { localize2WithPath, localizeWithPath } from '../../../../../nls.js';
import { MenuId, registerAction2, Action2 } from '../../../../../platform/actions/common/actions.js';
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
import { IsWindowsContext, IsLinuxContext } from '../../../../../platform/contextkey/common/contextkeys.js';
import { IQuickInputService } from '../../../../../platform/quickinput/common/quickInput.js';
import { Registry } from '../../../../../platform/registry/common/platform.js';
import { ViewAction } from '../../../../browser/parts/views/viewPane.js';
import { Extensions } from '../../../../common/contributions.js';
import { AccessibilityHelpAction } from '../../../accessibility/browser/accessibleViewActions.js';
import { runAccessibilityHelpAction } from './chatAccessibilityHelp.js';
import { IChatWidgetService } from '../chat.js';
import { ChatEditorInput } from '../chatEditorInput.js';
import { IChatAgentService } from '../../common/chatAgents.js';
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_INPUT_HAS_AGENT, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_INPUT, CONTEXT_PROVIDER_EXISTS, CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE, CONTEXT_REQUEST } from '../../common/chatContextKeys.js';
import { IChatContributionService } from '../../common/chatContributionService.js';
import { chatAgentLeader } from '../../common/chatParserTypes.js';
import { IChatService } from '../../common/chatService.js';
import { IChatWidgetHistoryService } from '../../common/chatWidgetHistoryService.js';
import { IEditorService } from '../../../../services/editor/common/editorService.js';
import { IViewsService } from '../../../../services/views/common/viewsService.js';
const CHAT_CATEGORY = ( localize2WithPath(
    'vs/workbench/contrib/chat/browser/actions/chatActions',
    'chat.category',
    'Chat'
));
const CHAT_OPEN_ACTION_ID = 'workbench.action.chat.open';
class OpenChatGlobalAction extends Action2 {
    constructor() {
        super({
            id: CHAT_OPEN_ACTION_ID,
            title: ( localize2WithPath(
                'vs/workbench/contrib/chat/browser/actions/chatActions',
                'openChat',
                "Open Chat"
            )),
            precondition: CONTEXT_PROVIDER_EXISTS,
            icon: Codicon.commentDiscussion,
            f1: false,
            category: CHAT_CATEGORY,
            keybinding: {
                weight: 200 ,
                primary: 2048  | 512  | 39 ,
                mac: {
                    primary: 2048  | 256  | 39
                }
            }
        });
    }
    async run(accessor, opts) {
        opts = typeof opts === 'string' ? { query: opts } : opts;
        const chatService = accessor.get(IChatService);
        const chatWidgetService = accessor.get(IChatWidgetService);
        const providers = chatService.getProviderInfos();
        if (!providers.length) {
            return;
        }
        const chatWidget = await chatWidgetService.revealViewForProvider(providers[0].id);
        if (!chatWidget) {
            return;
        }
        if (opts?.query) {
            if (opts.isPartialQuery) {
                chatWidget.setInput(opts.query);
            }
            else {
                chatWidget.acceptInput(opts.query);
            }
        }
        chatWidget.focusInput();
    }
}
class ChatSubmitSecondaryAgentEditorAction extends EditorAction2 {
    static { this.ID = 'workbench.action.chat.submitSecondaryAgent'; }
    constructor() {
        super({
            id: ChatSubmitSecondaryAgentEditorAction.ID,
            title: ( localize2WithPath(
                'vs/workbench/contrib/chat/browser/actions/chatActions',
                { key: 'actions.chat.submitSecondaryAgent', comment: ['Send input from the chat input box to the secondary agent'] },
                "Submit to Secondary Agent"
            )),
            precondition: ( ContextKeyExpr.and(CONTEXT_CHAT_INPUT_HAS_TEXT, ( CONTEXT_CHAT_INPUT_HAS_AGENT.negate()), ( CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate()))),
            keybinding: {
                when: CONTEXT_IN_CHAT_INPUT,
                primary: 2048  | 3 ,
                weight: 100
            },
            menu: {
                id: MenuId.ChatExecuteSecondary,
                group: 'group_1',
                when: ( CONTEXT_CHAT_INPUT_HAS_AGENT.negate()),
            }
        });
    }
    runEditorCommand(accessor, editor) {
        const editorUri = editor.getModel()?.uri;
        if (editorUri) {
            const agentService = accessor.get(IChatAgentService);
            const secondaryAgent = agentService.getSecondaryAgent();
            if (!secondaryAgent) {
                return;
            }
            const widgetService = accessor.get(IChatWidgetService);
            const widget = widgetService.getWidgetByInputUri(editorUri);
            if (!widget) {
                return;
            }
            if (widget.getInput().match(/^\s*@/)) {
                widget.acceptInput();
            }
            else {
                widget.acceptInputWithPrefix(`${chatAgentLeader}${secondaryAgent.name}`);
            }
        }
    }
}
class ChatSubmitEditorAction extends EditorAction2 {
    static { this.ID = 'workbench.action.chat.acceptInput'; }
    constructor() {
        super({
            id: ChatSubmitEditorAction.ID,
            title: ( localize2WithPath(
                'vs/workbench/contrib/chat/browser/actions/chatActions',
                { key: 'actions.chat.submit', comment: ['Apply input from the chat input box'] },
                "Submit"
            )),
            precondition: CONTEXT_CHAT_INPUT_HAS_TEXT,
            keybinding: {
                when: CONTEXT_IN_CHAT_INPUT,
                primary: 3 ,
                weight: 100
            },
            menu: {
                id: MenuId.ChatExecuteSecondary,
                when: ( CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate()),
                group: 'group_1',
            },
        });
    }
    runEditorCommand(accessor, editor) {
        const editorUri = editor.getModel()?.uri;
        if (editorUri) {
            const widgetService = accessor.get(IChatWidgetService);
            widgetService.getWidgetByInputUri(editorUri)?.acceptInput();
        }
    }
}
function registerChatActions() {
    registerAction2(OpenChatGlobalAction);
    registerAction2(ChatSubmitEditorAction);
    registerAction2(ChatSubmitSecondaryAgentEditorAction);
    registerAction2(class ClearChatInputHistoryAction extends Action2 {
        constructor() {
            super({
                id: 'workbench.action.chat.clearInputHistory',
                title: ( localize2WithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'interactiveSession.clearHistory.label',
                    "Clear Input History"
                )),
                precondition: CONTEXT_PROVIDER_EXISTS,
                category: CHAT_CATEGORY,
                f1: true,
            });
        }
        async run(accessor, ...args) {
            const historyService = accessor.get(IChatWidgetHistoryService);
            historyService.clearHistory();
        }
    });
    registerAction2(class ClearChatHistoryAction extends Action2 {
        constructor() {
            super({
                id: 'workbench.action.chat.clearHistory',
                title: ( localize2WithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'chat.clear.label',
                    "Clear All Workspace Chats"
                )),
                precondition: CONTEXT_PROVIDER_EXISTS,
                category: CHAT_CATEGORY,
                f1: true,
            });
        }
        async run(accessor, ...args) {
            const chatService = accessor.get(IChatService);
            chatService.clearAllHistoryEntries();
        }
    });
    registerAction2(class FocusChatAction extends EditorAction2 {
        constructor() {
            super({
                id: 'chat.action.focus',
                title: ( localize2WithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'actions.interactiveSession.focus',
                    'Focus Chat List'
                )),
                precondition: CONTEXT_IN_CHAT_INPUT,
                category: CHAT_CATEGORY,
                keybinding: [
                    {
                        when: CONTEXT_CHAT_INPUT_CURSOR_AT_TOP,
                        primary: 2048  | 16 ,
                        weight: 100 ,
                    },
                    {
                        when: ( ContextKeyExpr.or(IsWindowsContext, IsLinuxContext)),
                        primary: 2048  | 16 ,
                        weight: 100 ,
                    }
                ]
            });
        }
        runEditorCommand(accessor, editor) {
            const editorUri = editor.getModel()?.uri;
            if (editorUri) {
                const widgetService = accessor.get(IChatWidgetService);
                widgetService.getWidgetByInputUri(editorUri)?.focusLastMessage();
            }
        }
    });
    class ChatAccessibilityHelpContribution extends Disposable {
        constructor() {
            super();
            this._register(AccessibilityHelpAction.addImplementation(105, 'panelChat', async (accessor) => {
                const codeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor() || accessor.get(ICodeEditorService).getFocusedCodeEditor();
                runAccessibilityHelpAction(accessor, codeEditor ?? undefined, 'panelChat');
            }, ( ContextKeyExpr.or(CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE, CONTEXT_REQUEST))));
        }
    }
    const workbenchRegistry = ( Registry.as(Extensions.Workbench));
    workbenchRegistry.registerWorkbenchContribution(ChatAccessibilityHelpContribution, 4 );
    registerAction2(class FocusChatInputAction extends Action2 {
        constructor() {
            super({
                id: 'workbench.action.chat.focusInput',
                title: ( localize2WithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'interactiveSession.focusInput.label',
                    "Focus Chat Input"
                )),
                f1: false,
                keybinding: {
                    primary: 2048  | 18 ,
                    weight: 200 ,
                    when: ( ContextKeyExpr.and(CONTEXT_IN_CHAT_SESSION, ( CONTEXT_IN_CHAT_INPUT.negate())))
                }
            });
        }
        run(accessor, ...args) {
            const widgetService = accessor.get(IChatWidgetService);
            widgetService.lastFocusedWidget?.focusInput();
        }
    });
}
function getOpenChatEditorAction(id, label, when) {
    return class OpenChatEditor extends Action2 {
        constructor() {
            super({
                id: `workbench.action.openChat.${id}`,
                title: ( localize2WithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'interactiveSession.open',
                    "Open Editor ({0})",
                    label
                )),
                f1: true,
                category: CHAT_CATEGORY,
                precondition: ContextKeyExpr.deserialize(when)
            });
        }
        async run(accessor) {
            const editorService = accessor.get(IEditorService);
            await editorService.openEditor({ resource: ChatEditorInput.getNewEditorUri(), options: { target: { providerId: id }, pinned: true } });
        }
    };
}
const getHistoryChatActionDescriptorForViewTitle = (viewId, providerId) => ({
    viewId,
    id: `workbench.action.chat.${providerId}.history`,
    title: ( localize2WithPath(
        'vs/workbench/contrib/chat/browser/actions/chatActions',
        'chat.history.label',
        "Show Chats"
    )),
    menu: {
        id: MenuId.ViewTitle,
        when: ( ContextKeyExpr.equals('view', viewId)),
        group: 'navigation',
        order: -1
    },
    category: CHAT_CATEGORY,
    icon: Codicon.history,
    f1: true,
    precondition: CONTEXT_PROVIDER_EXISTS
});
function getHistoryAction(viewId, providerId) {
    return class HistoryAction extends ViewAction {
        constructor() {
            super(getHistoryChatActionDescriptorForViewTitle(viewId, providerId));
        }
        async runInView(accessor, view) {
            const chatService = accessor.get(IChatService);
            const quickInputService = accessor.get(IQuickInputService);
            const chatContribService = accessor.get(IChatContributionService);
            const viewsService = accessor.get(IViewsService);
            const items = chatService.getHistory();
            const picks = ( items.map(i => ({
                label: i.title,
                chat: i,
                buttons: [{
                        iconClass: ThemeIcon.asClassName(Codicon.x),
                        tooltip: ( localizeWithPath(
                            'vs/workbench/contrib/chat/browser/actions/chatActions',
                            'interactiveSession.history.delete',
                            "Delete"
                        )),
                    }]
            })));
            const selection = await quickInputService.pick(picks, {
                placeHolder: ( localizeWithPath(
                    'vs/workbench/contrib/chat/browser/actions/chatActions',
                    'interactiveSession.history.pick',
                    "Switch to chat"
                )),
                onDidTriggerItemButton: context => {
                    chatService.removeHistoryEntry(context.item.chat.sessionId);
                    context.removeItem();
                }
            });
            if (selection) {
                const sessionId = selection.chat.sessionId;
                const provider = chatContribService.registeredProviders[0]?.id;
                if (provider) {
                    const viewId = chatContribService.getViewIdForProvider(provider);
                    const view = await viewsService.openView(viewId);
                    view.loadSession(sessionId);
                }
            }
        }
    };
}
export { CHAT_CATEGORY, CHAT_OPEN_ACTION_ID, ChatSubmitEditorAction, ChatSubmitSecondaryAgentEditorAction, getHistoryAction, getOpenChatEditorAction, registerChatActions };
