"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AlertInternalApi = void 0;
const tslib_1 = require("tslib");
const ApiBase_1 = require("../Implementation/ApiBase");
const AdaptableQuery_1 = require("../../AdaptableState/Common/AdaptableQuery");
const AdaptableAlert_1 = require("../../AdaptableState/Common/AdaptableAlert");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/ArrayExtensions"));
const ModuleConstants_1 = require("../../Utilities/Constants/ModuleConstants");
const IAlertService_1 = require("../../Utilities/Services/Interface/IAlertService");
const ObjectFactory_1 = tslib_1.__importDefault(require("../../Utilities/ObjectFactory"));
const Helper_1 = tslib_1.__importDefault(require("../../Utilities/Helpers/Helper"));
const InternalRedux = tslib_1.__importStar(require("../../Redux/ActionsReducers/InternalRedux"));
const StringExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/StringExtensions"));
const GeneralConstants_1 = require("../../Utilities/Constants/GeneralConstants");
const AdaptableLogger_1 = require("../../agGrid/AdaptableLogger");
class AlertInternalApi extends ApiBase_1.ApiBase {
    getExpressionForAlertRule(alertRule) {
        var expression;
        expression = alertRule.BooleanExpression
            ? alertRule.BooleanExpression
            : alertRule.AggregatedBooleanExpression
                ? alertRule.AggregatedBooleanExpression
                : alertRule.ObservableExpression
                    ? alertRule.ObservableExpression
                    : undefined;
        return expression;
    }
    /**
     * Retrieves the Adaptable Form with the given name
     * @param name name of the Form
     */
    getAdaptableFormByName(name) {
        const alertForms = this.getAlertOptions().alertForms || [];
        return alertForms.find((f) => f.name === name)?.form;
    }
    /**
     * Retrieves all Alert Definitions in Alert State which are NOT Reactive (BooleanQuery)
     * @returns alert definitions
     */
    getNonReactiveAlertDefinitions(config) {
        return this.getAlertApi()
            .getAlertDefinitions(config)
            .filter((alertDef) => !(0, AdaptableQuery_1.isReactiveQuery)(alertDef.Rule));
    }
    /**
     * Retrieves all active (non-suspended) Alert Definitions in Alert State which are NOT Reactive (BooleanQuery)
     * @returns alert definitions
     */
    getActiveNonReactiveAlertDefinitions(config) {
        return this.getNonReactiveAlertDefinitions(config).filter((alertDef) => !alertDef.IsSuspended);
    }
    /**
     *
     * Retrieves all Alert Definitions in Alert State which are reactive (ObservableQuery & AggregationQuery)
     * @returns alert definitions
     */
    getReactiveAlertDefinitions(config) {
        return this.getAlertApi()
            .getAlertDefinitions(config)
            .filter((alertDef) => (0, AdaptableQuery_1.isReactiveQuery)(alertDef.Rule));
    }
    /**
     *
     * Retrieves all active (non-suspended) Alert Definitions in Alert State which are reactive (ObservableQuery & AggregationQuery)
     * @returns alert definitions
     */
    getActiveReactiveAlertDefinitions() {
        return this.getReactiveAlertDefinitions().filter((alertDef) => !alertDef.IsSuspended);
    }
    /**
     * Retrieves all Alert Definitions which prevent a Cell Edit
     * @returns alert definitions
     */
    getAlertDefinitionsWithPreventEdit(config) {
        return this.getActiveNonReactiveAlertDefinitions(config).filter((a) => a.AlertProperties != null && a.AlertProperties.PreventEdit === true);
    }
    /**
     * Retrieves all Alert Definitions which allow a Cell Edit
     *  @returns alert definitions
     */
    getAlertDefinitionsWithAllowEdit(config) {
        return this.getActiveNonReactiveAlertDefinitions(config).filter((a) => a.AlertProperties == null || a.AlertProperties.PreventEdit !== true);
    }
    /**
     * Runs after a button in an Alert Form is clicked
     */
    executeAlertButton(button, context) {
        if (button.Command) {
            let commands = button.Command;
            if (typeof commands === 'function') {
                commands(context);
                return;
            }
            if (!Array.isArray(commands)) {
                commands = [commands];
            }
            commands.forEach((command) => {
                const buttonOnClick = this.getAlertOptions().commandHandlers?.find((x) => x.name === command);
                buttonOnClick?.handler(button, context);
                this.executeAlertCommand(command, {
                    alertDefinition: context.alert.alertDefinition,
                    cellDataChangedInfo: (0, AdaptableAlert_1.isAdaptableCellChangedAlert)(context.alert)
                        ? context.alert.cellDataChangedInfo
                        : null,
                    rowDataChangedInfo: (0, AdaptableAlert_1.isAdaptableRowChangedAlert)(context.alert)
                        ? context.alert.rowDataChangedInfo
                        : null,
                    formData: context.formData,
                });
            });
        }
    }
    /**
     * Runs after an Alert Command is invoked
     * @param command Action which has been invoked
     * @param details Info about the Alert and Form
     */
    executeAlertCommand(command, details) {
        const { alertDefinition, cellDataChangedInfo: cellDataChangedInfo, rowDataChangedInfo: rowDataChangedInfo, } = details;
        const getBackgroundColor = (alertDefinition) => {
            const highlightType = alertDefinition.MessageType ?? 'Info';
            let backgroundColor = '';
            switch (highlightType) {
                case 'Error':
                    backgroundColor = 'var(--ab-color-error)';
                    break;
                case 'Info':
                    backgroundColor = 'var(--ab-color-info)';
                    break;
                case 'Success':
                    backgroundColor = 'var(--ab-color-success)';
                    break;
                case 'Warning':
                    backgroundColor = 'var(--ab-color-warn)';
            }
            return backgroundColor;
        };
        if (command === 'highlight-cell' && cellDataChangedInfo) {
            const backgroundColor = getBackgroundColor(alertDefinition);
            this.getGridApi().highlightCell({
                columnId: cellDataChangedInfo.column.columnId,
                primaryKeyValue: cellDataChangedInfo.primaryKeyValue,
                highlightStyle: {
                    BackColor: backgroundColor,
                },
                timeout: this.getAlertOptions().cellHighlightDuration,
            });
        }
        if (command === 'highlight-row' && cellDataChangedInfo) {
            const rowsHighlightInfo = {
                primaryKeyValues: [cellDataChangedInfo.primaryKeyValue],
                highlightStyle: {
                    BackColor: getBackgroundColor(alertDefinition),
                },
                timeout: this.getAlertOptions().rowHighlightDuration,
            };
            this.getGridApi().highlightRows(rowsHighlightInfo);
        }
        if (command === 'highlight-row' &&
            rowDataChangedInfo &&
            // no sense to highlight a deleted(non-existing) row
            rowDataChangedInfo?.rowTrigger !== 'Delete') {
            const primaryKeyValues = this.getGridApi().getPrimaryKeyValuesForRowNodes(rowDataChangedInfo.rowNodes);
            const rowsHighlightInfo = {
                primaryKeyValues,
                highlightStyle: {
                    BackColor: getBackgroundColor(alertDefinition),
                },
                timeout: this.getAlertOptions().rowHighlightDuration,
            };
            this.getGridApi().highlightRows(rowsHighlightInfo);
        }
        if (command === 'jump-to-cell' && cellDataChangedInfo) {
            this.getGridApi().jumpToCell(cellDataChangedInfo.primaryKeyValue, cellDataChangedInfo.column.columnId, cellDataChangedInfo.rowNode);
        }
        if (command === 'jump-to-row' &&
            // either a cell change
            (cellDataChangedInfo ||
                // or a grid change, but NOT row deletion
                (rowDataChangedInfo &&
                    // no sense to jump to a deleted(non-existing) row
                    rowDataChangedInfo?.rowTrigger !== 'Delete'))) {
            const [firstRowNode] = cellDataChangedInfo
                ? [cellDataChangedInfo.rowNode]
                : rowDataChangedInfo.rowNodes;
            const targetRowNodePrimaryKeyValue = this.getGridApi().getPrimaryKeyValueForRowNode(firstRowNode);
            if (targetRowNodePrimaryKeyValue) {
                this.getGridApi().jumpToRow(targetRowNodePrimaryKeyValue);
            }
        }
        if (command === 'jump-to-column' && cellDataChangedInfo) {
            this.getGridApi().jumpToColumn(cellDataChangedInfo.column.columnId);
        }
        if (command === 'suspend') {
            this.getAlertApi().suspendAlertDefinition(alertDefinition);
        }
        if (command === 'undo' && cellDataChangedInfo) {
            this.getGridApi().undoCellEdit(cellDataChangedInfo);
        }
    }
    /**
     * Retrieves all Predicate Defs that match given Scope
     * @param scope the Scope to check
     */
    getAlertPredicateDefsForScope(scope) {
        return this.getPredicateApi()
            .internalApi.getAlertPredicateDefs(scope)
            .filter((predicateDef) => this.getColumnScopeApi().isScopeInScope(scope, predicateDef.columnScope));
    }
    /**
     * Returns a description of an Alert Definition
     * @param alertDefinition Alert Definition to use
     */
    getAlertDescriptionForDataChange(alertDefinition, cellDataChangedInfo) {
        let customMessage = this.getCustomAlertDescription(alertDefinition, { cellDataChangedInfo });
        const anotationContext = cellDataChangedInfo
            ? {
                column: cellDataChangedInfo.column,
                rowNode: cellDataChangedInfo.rowNode,
                oldValue: cellDataChangedInfo.oldValue,
                newValue: cellDataChangedInfo.newValue,
                primaryKeyValue: cellDataChangedInfo.primaryKeyValue,
                timestamp: cellDataChangedInfo.changedAt,
                trigger: cellDataChangedInfo.trigger,
            }
            : {};
        if (customMessage) {
            customMessage = cellDataChangedInfo
                ? this.annotateAlertText(customMessage, anotationContext)
                : customMessage;
            return customMessage;
        }
        if (alertDefinition.MessageText != null) {
            let alertText = alertDefinition.MessageText;
            try {
                alertText = cellDataChangedInfo
                    ? this.annotateAlertText(alertText, anotationContext)
                    : alertText;
                return alertText;
            }
            catch (e) {
                this.logError('Error in getAlertMessageHeader', e);
            }
        }
        let scopeDescription = this.getColumnScopeApi().getScopeDescription(alertDefinition.Scope);
        let ruleDescription = this.getAlertRuleDescription(alertDefinition);
        return scopeDescription + ' - ' + ruleDescription;
    }
    /**
     * Returns a description title of an Alert Definition
     * @param alertDefinition Alert Definition to use
     */
    getAlertMessageHeaderForDataChange(alertDefinition, cellDataChangedInfo) {
        const anotationContext = cellDataChangedInfo
            ? {
                column: cellDataChangedInfo.column,
                rowNode: cellDataChangedInfo.rowNode,
                oldValue: cellDataChangedInfo.oldValue,
                newValue: cellDataChangedInfo.newValue,
                primaryKeyValue: cellDataChangedInfo.primaryKeyValue,
                timestamp: cellDataChangedInfo.changedAt,
                trigger: cellDataChangedInfo.trigger,
            }
            : {};
        let message = this.getCustomAlertMessageHeader(alertDefinition, {
            cellDataChangedInfo,
        }) ?? cellDataChangedInfo?.column?.friendlyName;
        try {
            message = cellDataChangedInfo ? this.annotateAlertText(message, anotationContext) : message;
        }
        catch (e) {
            this.logError('Error in getAlertMessageHeader', e);
        }
        return message;
    }
    getAlertMessageForRowDataChange(alertDefinition, rowDataChangedInfo) {
        const rowAdded = rowDataChangedInfo.rowTrigger === 'Add';
        const numberOfChangedRows = rowDataChangedInfo.rowNodes.length;
        const actionName = rowAdded ? 'Added' : 'Removed';
        const defaultMessage = numberOfChangedRows > 1
            ? `${numberOfChangedRows} rows were ${actionName.toLowerCase()}`
            : `${numberOfChangedRows} row was ${actionName.toLowerCase()}`;
        const customMessage = this.getCustomAlertDescription(alertDefinition, {
            rowDataChangedInfo: rowDataChangedInfo,
        });
        let alertMessage = alertDefinition.MessageText
            ? alertDefinition.MessageText
            : customMessage ?? defaultMessage;
        try {
            alertMessage = this.annotateAlertText(alertMessage, {
                numberOfRows: numberOfChangedRows,
                timestamp: rowDataChangedInfo.changedAt,
                trigger: rowDataChangedInfo.rowTrigger,
            });
        }
        catch (e) {
            this.logError('Error in getAlertMessageForRowDataChange', e);
        }
        return alertMessage;
    }
    getAlertHeaderForRowDataChange(alertDefinition, rowDataChangedInfo) {
        const rowAdded = rowDataChangedInfo.rowTrigger === 'Add';
        const numberOfChangedRows = rowDataChangedInfo.rowNodes.length;
        const actionName = rowAdded ? 'Added' : 'Removed';
        const customHeader = this.getCustomAlertMessageHeader(alertDefinition, {
            rowDataChangedInfo: rowDataChangedInfo,
        });
        const alertHeader = numberOfChangedRows > 1 ? `${actionName} Rows` : `${actionName} Row `;
        let header = customHeader ?? alertHeader;
        try {
            header = this.annotateAlertText(header, {
                numberOfRows: numberOfChangedRows,
                timestamp: rowDataChangedInfo.changedAt,
                trigger: rowDataChangedInfo.rowTrigger,
            });
        }
        catch (e) {
            this.logError('Error in getAlertHeaderForRowDataChange', e);
        }
        return header;
    }
    /**
     * Returns custom description for alert using the 'alertMessageText' property
     *
     * @param alertDefinition Alert Definition to use
     * @param dataChangedInfo data change info, it can be eighter grid or cell data chantged info
     */
    getCustomAlertDescription(alertDefinition, dataChangedInfo) {
        const alertMessageFunction = this.getAlertOptions()?.alertMessageText;
        if (alertMessageFunction) {
            const alertMessageContext = {
                alertDefinition: alertDefinition,
                cellDataChangedInfo: dataChangedInfo.cellDataChangedInfo,
                rowDataChangedInfo: dataChangedInfo.rowDataChangedInfo,
            };
            const returnText = alertMessageFunction(alertMessageContext);
            if (returnText) {
                return returnText;
            }
        }
        return null;
    }
    /**
     * Returns custom title defined by 'alertMessageHeader' property
     * @param alertDefinition Alert Definition to use
     * @param dataChangedInfo Data change info, it can be eighter grid or cell data chantged info
     */
    getCustomAlertMessageHeader(alertDefinition, dataChangedInfo) {
        const alertMessageFunction = this.getAlertOptions()?.alertMessageHeader;
        if (alertMessageFunction) {
            const returnText = alertMessageFunction({
                alertDefinition,
                cellDataChangedInfo: dataChangedInfo?.cellDataChangedInfo,
                rowDataChangedInfo: dataChangedInfo?.rowDataChangedInfo,
            });
            if (returnText) {
                return returnText;
            }
        }
        if (alertDefinition.MessageHeader) {
            return alertDefinition.MessageHeader;
        }
        return null;
    }
    /**
     * Returns a description of an Alert Definition's Rule
     * @param alertDefinition Alert Definition to use
     */
    getAlertRuleDescription(alertDefinition) {
        let ruleDescription = alertDefinition.Rule?.Predicates?.length
            ? alertDefinition.Rule?.Predicates?.map((predicate) => this.getPredicateApi().predicateToString(predicate)).join(' AND ')
            : this.getAdaptableInternalApi().getAdaptableQueryExpressionText(alertDefinition.Rule);
        return ruleDescription;
    }
    /**
     * Was Adaptable Alert fired due to a Cell Change
     * @param alert AdaptableAlert to check
     */
    isCellChangedAdaptableAlert(alert) {
        return alert.alertType === 'cellChanged';
    }
    /**
     * Was Adaptable Alert fired due to a Row Change
     * @param alert AdaptableAlert to check
     */
    isRowChangedAdaptableAlert(alert) {
        return alert.alertType === 'rowChanged';
    }
    /**
     * Is Adaptable Alert a Generic one
     * @param alert AdaptableAlert to check
     */
    isGenericAdaptableAlert(alert) {
        return alert.alertType === 'generic';
    }
    /**
     * Returns for the Alert Type for an Adaptable Alert
     * @param alert AdaptableAlert to check
     */
    getAlertTypeForAdaptableAlert(alert) {
        return alert.alertType;
    }
    getAdaptableFormFromAlertForm(alertForm, context, defaultMessageType) {
        let adaptableAlertForm;
        let isActionForm = false;
        if (typeof alertForm === 'string') {
            const alertForms = this.getAlertOptions().alertForms || [];
            adaptableAlertForm = alertForms.find((f) => f.name === alertForm)?.form;
        }
        else {
            adaptableAlertForm = {
                ...alertForm,
                buttons: (alertForm.Buttons || []).map((alertButton) => {
                    return {
                        ...alertButton,
                        onClick: () => {
                            this.executeAlertButton(alertButton, context);
                        },
                    };
                }),
            };
            isActionForm = true;
        }
        if (!adaptableAlertForm) {
            return;
        }
        if (adaptableAlertForm && adaptableAlertForm.buttons) {
            // dont mutate the form, but clone it
            adaptableAlertForm = { ...adaptableAlertForm };
            adaptableAlertForm.buttons = adaptableAlertForm.buttons?.map((button) => {
                let buttonStyle = isActionForm
                    ? button.ButtonStyle
                    : this.getAdaptableInternalApi().getStyleForButton(button, context);
                if (defaultMessageType && !buttonStyle?.tone) {
                    // force the button tone to be the alert tone, if the tone is missing from button style (or button style non-existent)
                    buttonStyle = {
                        ...buttonStyle,
                        tone: defaultMessageType.toLowerCase(),
                    };
                }
                let label = isActionForm
                    ? button.Label
                    : this.getAdaptableInternalApi().getLabelForButton(button, context);
                return {
                    ...button,
                    buttonStyle,
                    label,
                };
            });
        }
        return adaptableAlertForm;
    }
    clearAdaptableAlerts() {
        this.dispatchAction(InternalRedux.AdaptableAlertDeleteAll([]));
    }
    getAdaptableAlerts() {
        return this.getAdaptableState().Internal.AdaptableAlerts ?? [];
    }
    getAdaptableCellChangedAlerts() {
        return this.getAdaptableAlerts().filter(AdaptableAlert_1.isAdaptableCellChangedAlert);
    }
    getAdaptableRowChangedAlerts() {
        return this.getAdaptableAlerts().filter(AdaptableAlert_1.isAdaptableRowChangedAlert);
    }
    getAdaptableAlertWithHighlightCell(columnId, rowNode) {
        // only alerts triggered by cell changes are relevant for HighlightCell actions
        return this.getAdaptableCellChangedAlerts().find((alert) => alert.alertDefinition.AlertProperties?.HighlightCell &&
            alert.cellDataChangedInfo?.column?.columnId === columnId &&
            alert.cellDataChangedInfo?.rowNode === rowNode);
    }
    getAdaptableAlertWithHighlightRow(rowNode) {
        let alertWithRowHighlight;
        alertWithRowHighlight = this.getAdaptableRowChangedAlerts().find((alert) => {
            if (alert.alertDefinition.AlertProperties?.HighlightRow) {
                if (alert.rowDataChangedInfo?.rowNodes.map((rowNode) => rowNode.id).includes(rowNode.id)) {
                    return alert;
                }
            }
        });
        if (alertWithRowHighlight) {
            return alertWithRowHighlight;
        }
        alertWithRowHighlight = this.getAdaptableCellChangedAlerts().find((alert) => {
            if (alert.alertDefinition.AlertProperties?.HighlightRow) {
                if (alert.cellDataChangedInfo?.rowNode.id == rowNode.id) {
                    return alert;
                }
            }
        });
        return alertWithRowHighlight;
    }
    isAlertDefinitionForAddedRowChangeEvent(alertDefinition) {
        const observableExpression = alertDefinition?.Rule?.ObservableExpression;
        if (StringExtensions_1.default.IsNotNullOrEmpty(observableExpression)) {
            return observableExpression.includes(GeneralConstants_1.OBSERVABLE_EXPRESSION_ROW_ADDED);
        }
        return false;
    }
    isAlertDefinitionForRemovedRowChangeEvent(alertDefinition) {
        const observableExpression = alertDefinition?.Rule?.ObservableExpression;
        if (StringExtensions_1.default.IsNotNullOrEmpty(observableExpression)) {
            return observableExpression.includes(GeneralConstants_1.OBSERVABLE_EXPRESSION_ROW_REMOVED);
        }
        return false;
    }
    setUpReactiveAlerts() {
        const reactiveAlertDefinitions = this.getActiveReactiveAlertDefinitions();
        reactiveAlertDefinitions.forEach((reactiveAlertDefinition) => this.getAdaptableInternalApi().getAlertService().createReactiveAlert(reactiveAlertDefinition));
    }
    getAlertDefinitionsForCellDataChange(dataChangedEvent) {
        const allActiveNonReactiveDefinitions = this.getActiveNonReactiveAlertDefinitions();
        let relatedAlertDefinitions = allActiveNonReactiveDefinitions
            .filter((v) => this.getColumnScopeApi().isColumnInScope(dataChangedEvent.column, v.Scope))
            .filter((alertDefinition) => !(0, AdaptableQuery_1.isReactiveQuery)(alertDefinition.Rule));
        let triggeredAlerts = [];
        if (ArrayExtensions_1.default.IsNotNullOrEmpty(relatedAlertDefinitions)) {
            relatedAlertDefinitions.forEach((alertDefinition) => {
                if (alertDefinition.Rule.BooleanExpression) {
                    let expression = alertDefinition.Rule.BooleanExpression;
                    let rowNode = dataChangedEvent.rowNode;
                    if (!rowNode) {
                        rowNode = this.getGridApi().getRowNodeForPrimaryKey(dataChangedEvent.primaryKeyValue);
                    }
                    const isValidExpression = this.getExpressionApi().isValidBooleanExpression(expression, 'Alert', `Invalid Alert boolean expression '${expression}'`);
                    let isSatisfiedExpression = false;
                    try {
                        isSatisfiedExpression =
                            isValidExpression &&
                                this.getAdaptableApi()
                                    .internalApi.getQueryLanguageService()
                                    .evaluateBooleanExpression(expression, 'Alert', rowNode, { dataChangedEvent });
                    }
                    catch (error) {
                        isSatisfiedExpression = false;
                        (0, AdaptableLogger_1.errorOnce)(error.message);
                    }
                    if (isSatisfiedExpression) {
                        triggeredAlerts.push(alertDefinition);
                    }
                }
                else if (alertDefinition.Rule.AggregatedBooleanExpression) {
                    const isValidExpression = this.getExpressionApi().isValidAggregatedBooleanExpression(alertDefinition.Rule.AggregatedBooleanExpression, 'Alert', `Invalid Alert boolean expression '${alertDefinition.Rule.AggregatedBooleanExpression}'`);
                    const isSatisfiedExpression = isValidExpression &&
                        this.isAggregationAlertTriggered(alertDefinition, dataChangedEvent);
                    if (isSatisfiedExpression) {
                        triggeredAlerts.push(alertDefinition);
                    }
                }
                else {
                    if (!this.isAlertDefinitionForRowChangeEvent(alertDefinition) &&
                        this.isAlertPredicateTriggered(alertDefinition, dataChangedEvent)) {
                        triggeredAlerts.push(alertDefinition);
                    }
                }
            });
            ``;
        }
        return triggeredAlerts;
    }
    isAggregationAlertTriggered(alertDefinition, dataChangedEvent) {
        const changedColumn = dataChangedEvent.column.columnId;
        const expressionAggregationColumns = this.getExpressionApi().getColumnsFromExpression(alertDefinition.Rule.AggregatedBooleanExpression);
        if (!expressionAggregationColumns.includes(changedColumn)) {
            return false;
        }
        const aggregatedBooleanValue = this.getAdaptableInternalApi()
            .getQueryLanguageService()
            .computeAggregatedBooleanValue(alertDefinition.Rule.AggregatedBooleanExpression, ModuleConstants_1.AlertModuleId);
        return aggregatedBooleanValue;
    }
    isAlertPredicateTriggered(alert, dataChangedEvent, defaultNoPredicateReturn = false) {
        const predicateDefHandlerContext = {
            value: dataChangedEvent.newValue,
            oldValue: dataChangedEvent.oldValue,
            rawValue: dataChangedEvent.newValue,
            displayValue: dataChangedEvent.newValue,
            node: dataChangedEvent.rowNode,
            column: dataChangedEvent.column,
            ...this.getAdaptableInternalApi().buildBaseContext(),
        };
        return this.getPredicateApi().handleColumnPredicates(alert.Rule?.Predicates, predicateDefHandlerContext, defaultNoPredicateReturn);
    }
    isAlertDefinitionForRowChangeEvent(alertDefinition) {
        return (this.isAlertDefinitionForAddedRowChangeEvent(alertDefinition) ||
            this.isAlertDefinitionForRemovedRowChangeEvent(alertDefinition));
    }
    showAlertForDefinitions(dataChangedInfo, alertDefinitions = []) {
        if ((0, IAlertService_1.isCellDataChangedInfo)(dataChangedInfo)) {
            alertDefinitions.forEach((alertDefinition) => {
                if (this.shouldFireAlertOnClient(alertDefinition)) {
                    const alert = ObjectFactory_1.default.CreateCellChangedAlert(this.getAlertMessageHeaderForDataChange(alertDefinition, dataChangedInfo), this.getAlertDescriptionForDataChange(alertDefinition, dataChangedInfo), alertDefinition, dataChangedInfo);
                    this.getAlertApi().displayAdaptableAlert(alert);
                }
            });
        }
        else {
            this.showAlertsForRowDataChanges(dataChangedInfo, alertDefinitions);
        }
    }
    showAlertsForRowDataChanges(rowDataChangedInfo, alertDefinitions) {
        alertDefinitions?.forEach((alertDefinition) => {
            if (this.shouldFireAlertOnClient(alertDefinition)) {
                const alert = ObjectFactory_1.default.CreateRowChangedAlert(this.getAlertHeaderForRowDataChange(alertDefinition, rowDataChangedInfo), this.getAlertMessageForRowDataChange(alertDefinition, rowDataChangedInfo), alertDefinition, rowDataChangedInfo);
                this.getAlertApi().displayAdaptableAlert(alert);
            }
        });
    }
    shouldFireAlertOnClient(alertDefinition) {
        const rule = alertDefinition.Rule;
        if (rule) {
            if (rule.Predicates) {
                return this.getExpressionApi().internalApi.shouldEvaluatePredicatesInAdaptableQL('Alert', alertDefinition, alertDefinition.Rule.Predicates);
            }
            else {
                var expression = this.getExpressionForAlertRule(rule);
                return this.getExpressionApi().internalApi.evaluateExpressionInAdaptableQL('Alert', alertDefinition, expression);
            }
        }
        return true;
    }
    getDefaultAlertNotificationForm() {
        // we still need the default Notification Form  for historical reasons
        // (i.e. to be able to display the AlertForm with the default buttons when the user has not defined any buttons)
        return {
            fields: [],
            Buttons: [this.getDefaultButton()],
        };
    }
    getDefaultButton() {
        return {
            Label: 'OK',
            ButtonStyle: {
                variant: 'raised',
            },
        };
    }
    /**
     * Supported tokens:
     * - column-that-changed-name -> [column]
     * - rowData.newValue -> [rowData.newValue]
     * - rowData.oldValue -> [rowData.oldValue]
     * - primaryKey -> [primaryKeyValue]
     * - timestamp -> [timestamp]
     * - trigger -> [trigger]
     */
    annotateAlertText(text, context) {
        if (!text) {
            return text;
        }
        if (!context) {
            return text;
        }
        if (context?.newValue) {
            text = Helper_1.default.replaceAll(text, '[newValue]', context.newValue);
        }
        if (context?.oldValue) {
            text = Helper_1.default.replaceAll(text, '[oldValue]', context.oldValue);
        }
        if (context?.primaryKeyValue) {
            text = Helper_1.default.replaceAll(text, '[primaryKeyValue]', context.primaryKeyValue);
        }
        if (context?.timestamp) {
            text = Helper_1.default.replaceAll(text, '[timestamp]', context.timestamp + '');
        }
        if (context?.numberOfRows) {
            text = Helper_1.default.replaceAll(text, '[numberOfRows]', context.numberOfRows + '');
        }
        if (context?.trigger) {
            const dataChangeTriggerMap = {
                edit: 'Edit',
                tick: 'Tick',
                undo: 'Undo',
                aggChange: 'AggChange',
            };
            const rowChangeTriggerMap = {
                Add: 'Added',
                Edit: 'Edited',
                Delete: 'Deleted',
                Load: 'Loaded',
            };
            const mappedTrigger = 
            // @ts-ignore
            (dataChangeTriggerMap[context.trigger] || rowChangeTriggerMap[context.trigger]) ??
                context.trigger;
            text = Helper_1.default.replaceAll(text, '[trigger]', mappedTrigger);
        }
        if (context?.column) {
            text = Helper_1.default.replaceAll(text, '[column]', this.getColumnApi().getFriendlyNameForColumnId(context.column.columnId));
        }
        if (context?.rowNode) {
            const columns = Helper_1.default.extractColsFromText(text);
            for (const column of columns) {
                if (this.getColumnApi().getColumnWithColumnId(column)) {
                    text = Helper_1.default.replaceAll(text, `[rowData.${column}]`, this.getGridApi().getRawValueFromRowNode(context.rowNode, column));
                }
            }
        }
        if (text.indexOf('[context') !== -1) {
            const agGridContext = this.getAdaptableInternalApi()
                .getAgGridAdapter()
                .getGridOption?.('context');
            const agGridContextKeys = Helper_1.default.extractContextKeysFromText(text);
            for (const key of agGridContextKeys) {
                if (agGridContext[key]) {
                    text = Helper_1.default.replaceAll(text, `[context.${key}]`, agGridContext[key]);
                }
            }
        }
        return text;
    }
}
exports.AlertInternalApi = AlertInternalApi;
