import { AdaptableModuleBase } from './AdaptableModuleBase';
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
import { MathOperation } from '../AdaptableState/Common/Enums';
import { PreviewHelper } from '../Utilities/Helpers/PreviewHelper';
import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
import ObjectFactory from '../Utilities/ObjectFactory';
export class SmartEditModule extends AdaptableModuleBase {
    constructor(api) {
        super(ModuleConstants.SmartEditModuleId, ModuleConstants.SmartEditFriendlyName, 'edit', 'SmartEditPopup', 'Edit groups of numeric cells using mathematical operations (e.g. Multiply by 10)', api);
    }
    getViewAccessLevel() {
        return 'Full';
    }
    createContextMenuItems(menuContext) {
        // not sure if this is right but logic is that
        // if the context cell is one of a selection taht can have smart edit applied
        // then open the smart edit screen
        // perhaps this is faulty logic though?
        let menuItemShowPopup = undefined;
        if (!menuContext.isRowGroupColumn && this.isModuleEditable()) {
            if (menuContext.adaptableColumn &&
                menuContext.adaptableColumn.dataType == 'number' &&
                menuContext.isSelectedCell &&
                menuContext.isSingleSelectedColumn &&
                this.api.gridApi.isEveryCellEditable(menuContext.selectedCellInfo.gridCells)) {
                let popUpParams = {
                    source: 'ContextMenu',
                };
                menuItemShowPopup = this.createMainMenuItemShowPopup({
                    Name: 'smart-edit-apply',
                    Label: 'Apply Smart Edit',
                    ComponentName: this.moduleInfo.Popup,
                    Icon: this.moduleInfo.Glyph,
                    PopupParams: popUpParams,
                });
            }
        }
        return [menuItemShowPopup];
    }
    CheckCorrectCellSelection() {
        let selectedCellInfo = this.api.gridApi.getSelectedCellInfo();
        if (this.api.layoutApi.isCurrentLayoutPivot()) {
            return {
                Alert: {
                    alertType: 'generic',
                    header: 'Smart Edit Error',
                    message: 'Cannot edit while Grid is in Pivot Mode.',
                    alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
                },
            };
        }
        if (selectedCellInfo == null || ArrayExtensions.IsNullOrEmpty(selectedCellInfo.columns)) {
            return {
                Alert: {
                    alertType: 'generic',
                    header: 'Smart Edit Error',
                    message: 'No cells are selected.\nPlease select some cells.',
                    alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
                },
            };
        }
        if (ArrayExtensions.NotCorrectLength(selectedCellInfo.columns, 1)) {
            return {
                Alert: {
                    alertType: 'generic',
                    header: 'Smart Edit Error',
                    message: 'Smart Edit only supports single column edit.\nPlease adjust cell selection.',
                    alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
                },
            };
        }
        let column = selectedCellInfo.columns[0];
        if (column) {
            if (column.dataType != 'number') {
                return {
                    Alert: {
                        alertType: 'generic',
                        header: 'Smart Edit Error',
                        message: 'Smart Edit only supports editing of numeric columns.\nPlease adjust the cell selection.',
                        alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
                    },
                };
            }
        }
        if (ArrayExtensions.IsNotNullOrEmpty(selectedCellInfo.gridCells) &&
            !this.api.gridApi.isEveryCellEditable(selectedCellInfo.gridCells)) {
            return {
                Alert: {
                    alertType: 'generic',
                    header: 'Smart Edit Error',
                    message: 'Smart Edit is not permitted on readonly cells.\nPlease adjust the cell selection.',
                    alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
                },
            };
        }
        return { ActionReturn: true };
    }
    BuildPreviewValues(smartEditValue, smartEditOperation) {
        let selectedCellInfo = this.api.gridApi.getSelectedCellInfo();
        let previewResults = [];
        let column;
        if (!this.api.layoutApi.isCurrentLayoutPivot()) {
            if (ArrayExtensions.IsNotNullOrEmpty(selectedCellInfo.columns)) {
                column = this.api.columnApi.getColumnWithColumnId(selectedCellInfo.columns[0].columnId);
                if (column) {
                    selectedCellInfo.gridCells.forEach((selectedCell) => {
                        let newValue;
                        if (typeof smartEditOperation === 'object') {
                            const context = {
                                smartEditValue: smartEditValue,
                                currentCell: selectedCell,
                                ...this.api.internalApi.buildBaseContext(),
                            };
                            newValue = smartEditOperation.operation(context);
                        }
                        else {
                            switch (smartEditOperation) {
                                case MathOperation.Add:
                                    newValue = Number(selectedCell.rawValue) + smartEditValue;
                                    break;
                                case MathOperation.Subtract:
                                    newValue = Number(selectedCell.rawValue) - smartEditValue;
                                    break;
                                case MathOperation.Multiply:
                                    newValue = Number(selectedCell.rawValue) * smartEditValue;
                                    break;
                                case MathOperation.Divide:
                                    newValue = Number(selectedCell.rawValue) / smartEditValue;
                                    break;
                            }
                        }
                        //avoid the 0.0000000000x
                        if (newValue) {
                            newValue = parseFloat(newValue.toFixed(12));
                        }
                        let dataChangedEvent = this.api.internalApi.buildCellDataChangedInfo({
                            oldValue: Number(selectedCell.rawValue),
                            newValue: newValue,
                            column: selectedCell.column,
                            primaryKeyValue: selectedCell.primaryKeyValue,
                            rowNode: selectedCell.rowNode,
                            trigger: 'edit',
                        });
                        let validationRules = this.api.internalApi
                            .getValidationService()
                            .getValidationRulesForDataChange(dataChangedEvent);
                        let previewResult = {
                            id: selectedCell.primaryKeyValue,
                            initialValue: Number(selectedCell.rawValue),
                            computedValue: newValue,
                            validationRules: validationRules,
                            rowNode: selectedCell.rowNode,
                        };
                        previewResults.push(previewResult);
                    });
                }
            }
        }
        return {
            column: column,
            previewResults: previewResults,
            previewValidationSummary: PreviewHelper.GetPreviewValidationSummary(previewResults),
        };
    }
}
