import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { KeyChord, KeyMod as KeyMod$1, KeyCode } from '../../../../base/common/keyCodes.js';
import { isNotificationViewItem } from '../../../common/notifications.js';
import { MenuRegistry, MenuId } from '../../../../platform/actions/common/actions.js';
import { localizeWithPath, localize2WithPath } from '../../../../nls.js';
import { WorkbenchList } from '../../../../platform/list/browser/listService.js';
import { IListService } from '../../../../platform/list/browser/listService.service.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.service.js';
import { notificationToMetrics } from './notificationsTelemetry.js';
import { NotificationsCenterVisibleContext, NotificationFocusedContext, NotificationsToastsVisibleContext } from '../../../common/contextkeys.js';
import { NotificationsFilter, NotificationPriority } from '../../../../platform/notification/common/notification.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { ActionRunner } from '../../../../base/common/actions.js';
import { hash } from '../../../../base/common/hash.js';
import { firstOrDefault } from '../../../../base/common/arrays.js';
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.service.js';
import { DisposableStore } from '../../../../base/common/lifecycle.js';
import { AccessibilitySignal } from '../../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';
import { IAccessibilitySignalService } from '../../../../platform/accessibilitySignal/browser/accessibilitySignalService.service.js';
const _moduleId = "vs/workbench/browser/parts/notifications/notificationsCommands";
const SHOW_NOTIFICATIONS_CENTER = 'notifications.showList';
const HIDE_NOTIFICATIONS_CENTER = 'notifications.hideList';
const TOGGLE_NOTIFICATIONS_CENTER = 'notifications.toggleList';
const HIDE_NOTIFICATION_TOAST = 'notifications.hideToasts';
const FOCUS_NOTIFICATION_TOAST = 'notifications.focusToasts';
const FOCUS_NEXT_NOTIFICATION_TOAST = 'notifications.focusNextToast';
const FOCUS_PREVIOUS_NOTIFICATION_TOAST = 'notifications.focusPreviousToast';
const FOCUS_FIRST_NOTIFICATION_TOAST = 'notifications.focusFirstToast';
const FOCUS_LAST_NOTIFICATION_TOAST = 'notifications.focusLastToast';
const COLLAPSE_NOTIFICATION = 'notification.collapse';
const EXPAND_NOTIFICATION = 'notification.expand';
const ACCEPT_PRIMARY_ACTION_NOTIFICATION = 'notification.acceptPrimaryAction';
const TOGGLE_NOTIFICATION = 'notification.toggle';
const CLEAR_NOTIFICATION = 'notification.clear';
const CLEAR_ALL_NOTIFICATIONS = 'notifications.clearAll';
const TOGGLE_DO_NOT_DISTURB_MODE = 'notifications.toggleDoNotDisturbMode';
const TOGGLE_DO_NOT_DISTURB_MODE_BY_SOURCE = 'notifications.toggleDoNotDisturbModeBySource';
function getNotificationFromContext(listService, context) {
    if (isNotificationViewItem(context)) {
        return context;
    }
    const list = listService.lastFocusedList;
    if (list instanceof WorkbenchList) {
        let element = list.getFocusedElements()[0];
        if (!isNotificationViewItem(element)) {
            if (list.isDOMFocused()) {
                element = list.element(0);
            }
        }
        if (isNotificationViewItem(element)) {
            return element;
        }
    }
    return undefined;
}
function registerNotificationCommands(center, toasts, model) {
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: SHOW_NOTIFICATIONS_CENTER,
        weight: KeybindingWeight.WorkbenchContrib,
        primary: KeyChord(KeyMod$1.CtrlCmd | KeyCode.KeyK, KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.KeyN),
        handler: () => {
            toasts.hide();
            center.show();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: HIDE_NOTIFICATIONS_CENTER,
        weight: KeybindingWeight.WorkbenchContrib + 50,
        when: NotificationsCenterVisibleContext,
        primary: KeyCode.Escape,
        handler: accessor => {
            const telemetryService = accessor.get(ITelemetryService);
            for (const notification of model.notifications) {
                if (notification.visible) {
                    telemetryService.publicLog2('notification:hide', notificationToMetrics(notification.message.original, notification.sourceId, notification.priority === NotificationPriority.SILENT));
                }
            }
            center.hide();
        }
    });
    CommandsRegistry.registerCommand(TOGGLE_NOTIFICATIONS_CENTER, () => {
        if (center.isVisible) {
            center.hide();
        }
        else {
            toasts.hide();
            center.show();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: CLEAR_NOTIFICATION,
        weight: KeybindingWeight.WorkbenchContrib,
        when: NotificationFocusedContext,
        primary: KeyCode.Delete,
        mac: {
            primary: KeyMod$1.CtrlCmd | KeyCode.Backspace
        },
        handler: (accessor, args) => {
            const accessibilitySignalService = accessor.get(IAccessibilitySignalService);
            const notification = getNotificationFromContext(accessor.get(IListService), args);
            if (notification && !notification.hasProgress) {
                notification.close();
                accessibilitySignalService.playSignal(AccessibilitySignal.clear);
            }
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: EXPAND_NOTIFICATION,
        weight: KeybindingWeight.WorkbenchContrib,
        when: NotificationFocusedContext,
        primary: KeyCode.RightArrow,
        handler: (accessor, args) => {
            const notification = getNotificationFromContext(accessor.get(IListService), args);
            notification?.expand();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: ACCEPT_PRIMARY_ACTION_NOTIFICATION,
        weight: KeybindingWeight.WorkbenchContrib,
        when: ( (ContextKeyExpr.or(NotificationFocusedContext, NotificationsToastsVisibleContext))),
        primary: KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.KeyA,
        handler: (accessor) => {
            const actionRunner = accessor.get(IInstantiationService).createInstance(NotificationActionRunner);
            const notification = getNotificationFromContext(accessor.get(IListService)) || firstOrDefault(model.notifications);
            if (!notification) {
                return;
            }
            const primaryAction = notification.actions?.primary ? firstOrDefault(notification.actions.primary) : undefined;
            if (!primaryAction) {
                return;
            }
            actionRunner.run(primaryAction, notification);
            notification.close();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: COLLAPSE_NOTIFICATION,
        weight: KeybindingWeight.WorkbenchContrib,
        when: NotificationFocusedContext,
        primary: KeyCode.LeftArrow,
        handler: (accessor, args) => {
            const notification = getNotificationFromContext(accessor.get(IListService), args);
            notification?.collapse();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: TOGGLE_NOTIFICATION,
        weight: KeybindingWeight.WorkbenchContrib,
        when: NotificationFocusedContext,
        primary: KeyCode.Space,
        secondary: [KeyCode.Enter],
        handler: accessor => {
            const notification = getNotificationFromContext(accessor.get(IListService));
            notification?.toggle();
        }
    });
    CommandsRegistry.registerCommand(HIDE_NOTIFICATION_TOAST, accessor => {
        const telemetryService = accessor.get(ITelemetryService);
        for (const notification of model.notifications) {
            if (notification.visible) {
                telemetryService.publicLog2('notification:hide', notificationToMetrics(notification.message.original, notification.sourceId, notification.priority === NotificationPriority.SILENT));
            }
        }
        toasts.hide();
    });
    KeybindingsRegistry.registerKeybindingRule({
        id: HIDE_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib - 50,
        when: NotificationsToastsVisibleContext,
        primary: KeyCode.Escape
    });
    KeybindingsRegistry.registerKeybindingRule({
        id: HIDE_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib + 100,
        when: ( (ContextKeyExpr.and(NotificationsToastsVisibleContext, NotificationFocusedContext))),
        primary: KeyCode.Escape
    });
    CommandsRegistry.registerCommand(FOCUS_NOTIFICATION_TOAST, () => toasts.focus());
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: FOCUS_NEXT_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib,
        when: ( (ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext))),
        primary: KeyCode.DownArrow,
        handler: () => {
            toasts.focusNext();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: FOCUS_PREVIOUS_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib,
        when: ( (ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext))),
        primary: KeyCode.UpArrow,
        handler: () => {
            toasts.focusPrevious();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: FOCUS_FIRST_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib,
        when: ( (ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext))),
        primary: KeyCode.PageUp,
        secondary: [KeyCode.Home],
        handler: () => {
            toasts.focusFirst();
        }
    });
    KeybindingsRegistry.registerCommandAndKeybindingRule({
        id: FOCUS_LAST_NOTIFICATION_TOAST,
        weight: KeybindingWeight.WorkbenchContrib,
        when: ( (ContextKeyExpr.and(NotificationFocusedContext, NotificationsToastsVisibleContext))),
        primary: KeyCode.PageDown,
        secondary: [KeyCode.End],
        handler: () => {
            toasts.focusLast();
        }
    });
    CommandsRegistry.registerCommand(CLEAR_ALL_NOTIFICATIONS, () => center.clearAll());
    CommandsRegistry.registerCommand(TOGGLE_DO_NOT_DISTURB_MODE, accessor => {
        const notificationService = accessor.get(INotificationService);
        notificationService.setFilter(notificationService.getFilter() === NotificationsFilter.ERROR ? NotificationsFilter.OFF : NotificationsFilter.ERROR);
    });
    CommandsRegistry.registerCommand(TOGGLE_DO_NOT_DISTURB_MODE_BY_SOURCE, accessor => {
        const notificationService = accessor.get(INotificationService);
        const quickInputService = accessor.get(IQuickInputService);
        const sortedFilters = notificationService.getFilters().sort((a, b) => a.label.localeCompare(b.label));
        const disposables = ( (new DisposableStore()));
        const picker = disposables.add(quickInputService.createQuickPick());
        picker.items = ( (sortedFilters.map(source => ({
            id: source.id,
            label: source.label,
            tooltip: `${source.label} (${source.id})`,
            filter: source.filter
        }))));
        picker.canSelectMany = true;
        picker.placeholder = ( localizeWithPath(_moduleId, 0, "Select sources to enable all notifications from"));
        picker.selectedItems = picker.items.filter(item => item.filter === NotificationsFilter.OFF);
        picker.show();
        disposables.add(picker.onDidAccept(async () => {
            for (const item of picker.items) {
                notificationService.setFilter({
                    id: item.id,
                    label: item.label,
                    filter: picker.selectedItems.includes(item) ? NotificationsFilter.OFF : NotificationsFilter.ERROR
                });
            }
            picker.hide();
        }));
        disposables.add(picker.onDidHide(() => disposables.dispose()));
    });
    const category = ( localize2WithPath(_moduleId, 1, 'Notifications'));
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: SHOW_NOTIFICATIONS_CENTER, title: ( localize2WithPath(_moduleId, 2, 'Show Notifications')), category } });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: HIDE_NOTIFICATIONS_CENTER, title: ( localize2WithPath(_moduleId, 3, 'Hide Notifications')), category }, when: NotificationsCenterVisibleContext });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: CLEAR_ALL_NOTIFICATIONS, title: ( localize2WithPath(_moduleId, 4, 'Clear All Notifications')), category } });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: ACCEPT_PRIMARY_ACTION_NOTIFICATION, title: ( localize2WithPath(_moduleId, 5, 'Accept Notification Primary Action')), category } });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: TOGGLE_DO_NOT_DISTURB_MODE, title: ( localize2WithPath(_moduleId, 6, 'Toggle Do Not Disturb Mode')), category } });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: TOGGLE_DO_NOT_DISTURB_MODE_BY_SOURCE, title: ( localize2WithPath(_moduleId, 7, 'Toggle Do Not Disturb Mode By Source...')), category } });
    MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: FOCUS_NOTIFICATION_TOAST, title: ( localize2WithPath(_moduleId, 8, 'Focus Notification Toast')), category }, when: NotificationsToastsVisibleContext });
}
let NotificationActionRunner = class NotificationActionRunner extends ActionRunner {
    constructor(telemetryService, notificationService) {
        super();
        this.telemetryService = telemetryService;
        this.notificationService = notificationService;
    }
    async runAction(action, context) {
        this.telemetryService.publicLog2('workbenchActionExecuted', { id: action.id, from: 'message' });
        if (isNotificationViewItem(context)) {
            this.telemetryService.publicLog2('notification:actionExecuted', {
                id: ( (hash(( (context.message.original.toString()))).toString())),
                actionLabel: action.label,
                source: context.sourceId || 'core',
                silent: context.priority === NotificationPriority.SILENT
            });
        }
        try {
            await super.runAction(action, context);
        }
        catch (error) {
            this.notificationService.error(error);
        }
    }
};
NotificationActionRunner = ( (__decorate([
    ( (__param(0, ITelemetryService))),
    ( (__param(1, INotificationService)))
], NotificationActionRunner)));
export { ACCEPT_PRIMARY_ACTION_NOTIFICATION, CLEAR_ALL_NOTIFICATIONS, CLEAR_NOTIFICATION, COLLAPSE_NOTIFICATION, EXPAND_NOTIFICATION, HIDE_NOTIFICATIONS_CENTER, HIDE_NOTIFICATION_TOAST, NotificationActionRunner, SHOW_NOTIFICATIONS_CENTER, TOGGLE_DO_NOT_DISTURB_MODE, TOGGLE_DO_NOT_DISTURB_MODE_BY_SOURCE, getNotificationFromContext, registerNotificationCommands };
