"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CellSummaryModule = void 0;
const tslib_1 = require("tslib");
const ModuleConstants = tslib_1.__importStar(require("../Utilities/Constants/ModuleConstants"));
const ArrayExtensions_1 = require("../Utilities/Extensions/ArrayExtensions");
const Helper_1 = require("../Utilities/Helpers/Helper");
const ObjectFactory_1 = tslib_1.__importDefault(require("../Utilities/ObjectFactory"));
const AggregatedScalarLiveValue_1 = require("../Utilities/Services/AggregatedScalarLiveValue");
const CellSummaryStatusPanel_1 = require("../View/CellSummary/CellSummaryStatusPanel");
const AdaptableModuleBase_1 = require("./AdaptableModuleBase");
class CellSummaryModule extends AdaptableModuleBase_1.AdaptableModuleBase {
    constructor(api) {
        super(ModuleConstants.CellSummaryModuleId, ModuleConstants.CellSummaryFriendlyName, 'cells', 'CellSummaryPopup', 'See summary information on a group of cells using multiple summary operations', api);
        this.cachedCellSummary = new WeakMap();
    }
    getViewAccessLevel() {
        return 'Full';
    }
    createColumnMenuItems(column) {
        if (!this.isModuleAvailable()) {
            return;
        }
        return [
            this.createMainMenuItemShowPopup({
                Name: 'cell-summary-show',
                Label: 'See Cell Summary',
                ComponentName: this.moduleInfo.Popup,
                Icon: this.moduleInfo.Glyph,
                PopupParams: {
                    source: 'ColumnMenu',
                    column,
                },
            }),
        ];
    }
    createContextMenuItems(menuContext) {
        if (!this.isModuleAvailable()) {
            return;
        }
        if (menuContext.adaptableColumn && menuContext.isSelectedCell) {
            return [
                this.createMainMenuItemShowPopup({
                    Name: 'cell-summary-show',
                    Label: 'See Cell Summary',
                    ComponentName: this.moduleInfo.Popup,
                    Icon: this.moduleInfo.Glyph,
                    PopupParams: {
                        source: 'ContextMenu',
                    },
                }),
            ];
        }
    }
    createCellSummary(selectedCellInfo) {
        if (this.cachedCellSummary.has(selectedCellInfo)) {
            return this.cachedCellSummary.get(selectedCellInfo);
        }
        let selectedCellSummary = ObjectFactory_1.default.CreateEmptyCellSummmary();
        if (selectedCellInfo && ArrayExtensions_1.ArrayExtensions.GetLength(selectedCellInfo.columns) === 1) {
            const selectedColumn = selectedCellInfo.columns[0];
            if (selectedColumn) {
                const isNumericColumn = selectedColumn.dataType === 'Number';
                const isDateColumn = selectedColumn.dataType === 'Date';
                const rowNodes = selectedCellInfo.gridCells.map((gc) => gc.rowNode);
                const handleExpression = (functionName) => {
                    const aggScalarValue = new AggregatedScalarLiveValue_1.AggregatedScalarLiveValue({
                        aggregatedScalarExpression: `${functionName}([${selectedColumn.columnId}])`,
                    }, ModuleConstants.CellSummaryModuleId, this.api, () => rowNodes);
                    let value = aggScalarValue.getGlobalAggregatedValue();
                    if (typeof value === 'number' && !isNaN(value)) {
                        value = Helper_1.Helper.roundNumber(value, 2);
                    }
                    return value;
                };
                const sumValue = isNumericColumn ? handleExpression('SUM') : null;
                const avgValue = isNumericColumn ? Helper_1.Helper.roundNumber(handleExpression('AVG'), 2) : null;
                const modeValue = isNumericColumn ? handleExpression('MODE') : null;
                const medianValue = isNumericColumn ? handleExpression('MEDIAN') : null;
                const distinctValue = handleExpression('DISTINCT');
                const maxValue = isNumericColumn || isDateColumn ? handleExpression('MAX') : null;
                const minValue = isNumericColumn || isDateColumn ? handleExpression('MIN') : null;
                const stdDeviation = isNumericColumn
                    ? Helper_1.Helper.roundNumberTo4dp(handleExpression('STD_DEVIATION'))
                    : null;
                selectedCellSummary = {
                    Sum: sumValue,
                    Average: avgValue,
                    Median: medianValue,
                    Mode: modeValue,
                    Distinct: distinctValue,
                    Max: maxValue,
                    Min: minValue,
                    Count: selectedCellInfo.gridCells.length,
                    Std_Deviation: stdDeviation,
                    Only: distinctValue == 1 ? JSON.stringify(selectedCellInfo.gridCells[0].rawValue) : '',
                };
                const weightedAverage = this.getWeightedAverageCellSummary(selectedColumn.columnId, rowNodes);
                if (weightedAverage !== null) {
                    selectedCellSummary.Weighted_Average = weightedAverage;
                }
                const operationDefinitions = this.api.cellSummaryApi.getCellSummaryOperationDefinitions();
                operationDefinitions === null || operationDefinitions === void 0 ? void 0 : operationDefinitions.forEach((operation) => {
                    if (operation.operationFunction) {
                        const cellSummaryOperationContext = Object.assign({ selectedCellInfo,
                            selectedColumn }, this.api.internalApi.buildBaseContext());
                        selectedCellSummary[operation.operationName] = operation.operationFunction(cellSummaryOperationContext);
                    }
                });
                this.cachedCellSummary.set(selectedCellInfo, selectedCellSummary);
            }
        }
        return selectedCellSummary;
    }
    getWeightedAverageCellSummary(columnId, rowNodes) {
        const currentLayout = this.api.layoutApi.getCurrentLayout();
        if (currentLayout.AggregationColumns == undefined) {
            return false;
        }
        const weightedAverageConfig = Object.entries(currentLayout.AggregationColumns).find(([colId, aggCol]) => typeof aggCol === 'object' && aggCol.type === 'weightedAverage' && colId === columnId);
        if (!weightedAverageConfig) {
            return null;
        }
        const { weightedColumnId } = weightedAverageConfig[1];
        const expression = `AVG([${columnId}], WEIGHT([${weightedColumnId}]))`;
        const aggScalarValue = new AggregatedScalarLiveValue_1.AggregatedScalarLiveValue({
            aggregatedScalarExpression: expression,
        }, ModuleConstants.CellSummaryModuleId, this.api, () => rowNodes);
        let value = aggScalarValue.getGlobalAggregatedValue();
        if (typeof value === 'number' && !isNaN(value)) {
            value = Helper_1.Helper.roundNumber(value, 2);
        }
        return value;
    }
    getViewProperties() {
        return {
            getStatusBarPanelProps() {
                /**
                 * This uses a custom view because it has special logic to
                 * trigger summary operations when the component is rendered.
                 */
                return {
                    view: CellSummaryStatusPanel_1.CellSummaryStatusPanel,
                };
            },
        };
    }
}
exports.CellSummaryModule = CellSummaryModule;
