import { SortOrder } from '../../AdaptableState/Common/Enums';
import * as InternalRedux from '../../Redux/ActionsReducers/InternalRedux';
import ArrayExtensions from '../../Utilities/Extensions/ArrayExtensions';
import { convertAdaptableStyleToCSS } from '../../Utilities/Helpers/StyleHelper';
import UIHelper from '../../View/UIHelper';
import { ApiBase } from '../Implementation/ApiBase';
export class GridInternalApi extends ApiBase {
    /**
     * Gets all distinct display values in the Column for given ColumnId
     * @param columnId Column to check
     */
    getDistinctDisplayValuesForColumnOld(columnId) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
        if (abColumn == undefined) {
            return [];
        }
        const returnValues = this._adaptable.getDistinctGridCellsForColumn(abColumn);
        return this.sortDistinctValues(returnValues, abColumn).map((cv) => {
            return cv.normalisedValue;
        });
    }
    /**
     * Gets all distinct Filter values for the Column with the given ColumnId
     * used for Floating Filter and Column Header filter
     * either returns a list of values or al ist a list of values with count
     *
     * This is a general method, and it is used in:
     * - Column Filters
     * - Query Builder
     * - Permitted Values
     *
     * @param columnId Column to check
     */
    async getDistinctFilterDisplayValuesForColumn(options) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(options.columnId);
        if (abColumn == undefined) {
            return [];
        }
        let gridCells = await this._adaptable.getDistinctFilterValuesForColumn({
            column: abColumn,
            get currentSearchValue() {
                return options.currentSearchValue;
            },
        });
        gridCells = gridCells || [];
        const valueOptions = gridCells.map((cv) => {
            return {
                label: cv.displayValue,
                value: cv.normalisedValue,
            };
        });
        return valueOptions;
    }
    async getDistinctValuesForColumn(columnId) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
        if (!abColumn) {
            return undefined;
        }
        const gridCells = await this._adaptable.getDistinctValuesForColumn(abColumn);
        return gridCells;
    }
    async getDistinctDisplayValuesForColumn(columnId) {
        const distinctValues = await this.getDistinctValuesForColumn(columnId);
        return distinctValues.map((gc) => {
            return gc.displayValue;
        });
    }
    async getDistinctEditDisplayValuesForColumn(options) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(options.columnId);
        if (!abColumn) {
            return undefined;
        }
        let gridCells = await this._adaptable.getDistinctEditValuesForColumn({
            column: abColumn,
            gridCell: options.gridCell,
            get currentSearchValue() {
                return options.currentSearchValue;
            },
        });
        gridCells = gridCells || [];
        return gridCells.map((gc) => {
            return {
                label: gc.displayValue,
                value: gc.normalisedValue,
            };
        });
    }
    /**
     * Gets all distinct raw values in Column. Values are sorted.
     * @param columnId Column to check
     */
    getDistinctRawValuesForColumn(columnId) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
        if (abColumn == undefined) {
            return [];
        }
        return this.sortDistinctValues(this.getUnsortedDistinctRawValuesForColumn(columnId), abColumn).map((cv) => {
            return cv.rawValue;
        });
    }
    /**
     * Gets all distinct raw values in Column. Values are un-sorted.
     * @param columnId Column to check
     */
    getUnsortedDistinctRawValuesForColumn(columnId) {
        const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
        if (abColumn == undefined) {
            return [];
        }
        return this._adaptable.getDistinctGridCellsForColumn(abColumn);
    }
    sortDistinctValues(returnValues, column) {
        // this does NOT into account Custom Sort - far too hard for now...
        let sortOrder = undefined;
        let columnSort = this.getGridApi().getColumnSortForColumn(column.columnId);
        if (columnSort && columnSort.SortOrder) {
            sortOrder =
                columnSort.SortOrder === 'Asc'
                    ? SortOrder.Asc
                    : columnSort.SortOrder === 'Desc'
                        ? SortOrder.Desc
                        : undefined;
        }
        if (sortOrder) {
            if (this.getColumnApi().hasNumberDataType(column?.columnId)) {
                returnValues = ArrayExtensions.sortCellValueArrayNumeric(returnValues, sortOrder);
            }
            else if (this.getColumnApi().hasDateDataType(column?.columnId)) {
                returnValues = ArrayExtensions.sortCellValueArrayDates(returnValues, sortOrder);
            }
            else {
                returnValues = ArrayExtensions.sortCellValueArray(returnValues, sortOrder);
            }
        }
        return returnValues;
    }
    setColumns(columns) {
        this.dispatchAction(InternalRedux.SetColumns(columns));
    }
    setSelectedCells(selectedCellInfo) {
        this.dispatchAction(InternalRedux.SetSelectedCells(selectedCellInfo));
    }
    setSelectedRows(selectedRowInfo) {
        this.dispatchAction(InternalRedux.SetSelectedRows(selectedRowInfo));
    }
    buildStandaloneColumnHeader(column) {
        return this._adaptable.agGridMenuAdapter.buildStandaloneColumnHeader(column);
    }
    getRowHighlightStyle(params) {
        const primaryKeyValue = this.getGridApi().getPrimaryKeyValueForRowNode(params.node);
        const highlightRow = this.getAdaptableInternalApi()
            .getInternalState()
            .RowHighlightInfo?.find((highlightRow) => {
            return highlightRow.primaryKeyValue === primaryKeyValue;
        });
        if (highlightRow) {
            return convertAdaptableStyleToCSS(highlightRow.highlightStyle);
        }
    }
    getAlertRowStyle(params) {
        const alert = this.getAlertApi().internalApi.getAdaptableAlertWithHighlightRow(params.node);
        const highlightRow = alert?.alertDefinition?.AlertProperties?.HighlightRow;
        if (highlightRow) {
            return typeof highlightRow === 'object'
                ? convertAdaptableStyleToCSS(highlightRow)
                : {
                    backgroundColor: UIHelper.getColorByMessageType(alert.alertDefinition.MessageType),
                };
        }
        return null;
    }
    getAlertRowClass(params) {
        const alert = this.getAlertApi().internalApi.getAdaptableAlertWithHighlightRow(params.node);
        const highlightRow = alert?.alertDefinition?.AlertProperties?.HighlightRow;
        return typeof highlightRow === 'object' && highlightRow?.ClassName
            ? highlightRow?.ClassName
            : null;
    }
    getRowHighlightClass(params) {
        const primaryKeyValue = this.getGridApi().getPrimaryKeyValueForRowNode(params.node);
        const highlightRow = this.getAdaptableInternalApi()
            .getInternalState()
            .RowHighlightInfo?.find((highlightRow) => {
            return highlightRow.primaryKeyValue === primaryKeyValue;
        });
        return typeof highlightRow?.highlightStyle === 'object'
            ? highlightRow.highlightStyle.ClassName
            : null;
    }
    deriveSpecialColumnSettingsFromAgGridDefaultColDef() {
        const defaultColumnDefinition = this._adaptable.agGridAdapter.getDefaultColumnDefinition();
        return {
            Filterable: defaultColumnDefinition.filter,
            Resizable: defaultColumnDefinition.resizable,
            Groupable: defaultColumnDefinition.enableRowGroup,
            Sortable: defaultColumnDefinition.sortable,
            Pivotable: defaultColumnDefinition.enablePivot,
            Aggregatable: defaultColumnDefinition.enableValue,
            SuppressMenu: defaultColumnDefinition.suppressHeaderMenuButton,
            SuppressMovable: defaultColumnDefinition.suppressMovable,
            HeaderToolTip: defaultColumnDefinition.headerTooltip,
            Width: defaultColumnDefinition.width,
        };
    }
    hasCellEditableAccordingToEditOptions() {
        return typeof this.getEditOptions()?.isCellEditable === 'function';
    }
    /**
     * Returns UNDEFINED if no EditOptions.isCellEditable is provided, otherwise returns the result of the function
     *
     * DO NOT USE THIS METHOD DIRECTLY - use `GridApi.isCellEditable` instead
     */
    isCellEditableAccordingToEditOptions(gridCell, defaultColDefinitionEditableValue) {
        const cellEditable = this.getEditOptions()?.isCellEditable;
        if (cellEditable) {
            const cellEditableContext = {
                ...this.getAdaptableInternalApi().buildBaseContext(),
                gridCell,
                defaultColDefEditableValue: defaultColDefinitionEditableValue,
            };
            return cellEditable(cellEditableContext);
        }
        return undefined;
    }
}
