"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StyledColumnInternalApi = void 0;
const tslib_1 = require("tslib");
const ApiBase_1 = require("../Implementation/ApiBase");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/ArrayExtensions"));
class StyledColumnInternalApi extends ApiBase_1.ApiBase {
    getMinValueForNumericColumn(column) {
        if (column.dataType !== 'number') {
            return undefined;
        }
        return this._adaptable.getMinMaxCachedValueForColumn(column, 'min');
    }
    getMaxValueForNumericColumn(column) {
        if (column.dataType !== 'number') {
            return undefined;
        }
        return this._adaptable.getMinMaxCachedValueForColumn(column, 'max');
    }
    /**
     * Gets the Minimum Value to display for a Styled Column
     * @param styledColumn Styled Column to check
     * @param rowNode current Row Node
     * @param cellValue current Cell Value
     */
    getNumericStyleMinValue(styledColumn, column, rowNode, cellValue) {
        const columnComparison = styledColumn.GradientStyle
            ? styledColumn.GradientStyle.ColumnComparison
            : styledColumn.PercentBarStyle?.ColumnComparison;
        if (columnComparison) {
            if (!isNaN(Number(columnComparison.MinValue))) {
                return Number(columnComparison.MinValue);
            }
            else {
                let columnId = columnComparison.MinValue;
                if (!this.getColumnApi().isColumnInGrid(columnId)) {
                    return 0;
                }
                else {
                    return this.getGridApi().getRawValueFromRowNode(rowNode, columnId);
                }
            }
        }
        // for Gradient Column we want just the range that contains cell value
        if (styledColumn.GradientStyle) {
            const range = this.findRangeForColumn(styledColumn.GradientStyle.CellRanges, column, styledColumn.GradientStyle.RangeValueType, cellValue);
            return this.getCellColorRangeMinValue(range, column, styledColumn.GradientStyle.RangeValueType);
        }
        // for percentbar we want to get the whole Ranges
        if (styledColumn.PercentBarStyle) {
            const ranges = styledColumn.PercentBarStyle?.CellRanges;
            if (ranges) {
                return this.getCellColorRangeMinValue(ranges[0], column, styledColumn.PercentBarStyle.RangeValueType);
            }
        }
    }
    /**
     * Returns last range that matches the cell value.
     *
     * @param cellRanges
     * @param column
     * @param rangeValueType
     * @param cellValue
     */
    findRangeForColumn(cellRanges, column, rangeValueType, cellValue) {
        if (!cellRanges || cellRanges.length === 0) {
            return null;
        }
        let lastMatchingRange = null;
        // findLast is not available on [], target is not es6
        for (let i = cellRanges.length; i >= 0; i--) {
            const cellRange = cellRanges[i];
            const minRange = this.getCellColorRangeMinValue(cellRange, column, rangeValueType);
            const maxRange = this.getCellColorRangeMaxValue(cellRange, column, rangeValueType);
            if (cellValue >= minRange && cellValue <= maxRange) {
                lastMatchingRange = cellRange;
                break;
            }
        }
        return lastMatchingRange;
    }
    /**
     * Gets the Maximum Value to display for a Styled Column
     * @param styledColumn Styled Column to check
     * @param rowNode current Row Node
     * @param cellValue current Cell Value
     */
    getNumericStyleMaxValue(styledColumn, column, rowNode, cellValue) {
        const columnComparison = styledColumn.GradientStyle
            ? styledColumn.GradientStyle.ColumnComparison
            : styledColumn.PercentBarStyle?.ColumnComparison;
        if (columnComparison) {
            if (!isNaN(Number(columnComparison.MaxValue))) {
                return Number(columnComparison.MaxValue);
            }
            else {
                let columnId = columnComparison.MaxValue;
                if (!this.getColumnApi().isColumnInGrid(columnId)) {
                    return 0;
                }
                else {
                    return this.getGridApi().getRawValueFromRowNode(rowNode, columnId);
                }
            }
        }
        if (styledColumn.GradientStyle) {
            let range = this.findRangeForColumn(styledColumn.GradientStyle.CellRanges, column, styledColumn.GradientStyle.RangeValueType, cellValue);
            return this.getCellColorRangeMaxValue(range, column, styledColumn.GradientStyle.RangeValueType);
        }
        if (styledColumn.PercentBarStyle) {
            const ranges = styledColumn.PercentBarStyle?.CellRanges;
            if (ranges) {
                return this.getCellColorRangeMaxValue(ranges[ranges.length - 1], column, styledColumn.PercentBarStyle.RangeValueType);
            }
        }
    }
    /**
     * Returns the smallest number in a Range
     * @param range Range to check
     * @param column current Column
     */
    getCellColorRangeMinValue(range, column, rangeValueType) {
        if (!range) {
            return undefined;
        }
        if (range.Min == undefined) {
            return undefined;
        }
        let minValue;
        if (typeof range.Min === 'number' && rangeValueType === 'Percentage') {
            const minColumnValue = this.getMinValueForNumericColumn(column);
            const maxColumnValue = this.getMaxValueForNumericColumn(column);
            minValue = minColumnValue + (range.Min / 100) * (maxColumnValue - minColumnValue);
        }
        else if (range.Min === 'Col-Min') {
            const minColumnValue = this.getMinValueForNumericColumn(column);
            minValue = minColumnValue;
        }
        else {
            minValue = range.Min;
        }
        return minValue;
    }
    /**
     * Returns the largest number in a Range
     * @param range Range to check
     * @param column current Column
     */
    getCellColorRangeMaxValue(range, column, rangeValueType) {
        if (!range) {
            return undefined;
        }
        if (range.Max == undefined) {
            return undefined;
        }
        let maxValue;
        if (typeof range.Max === 'number' && rangeValueType === 'Percentage') {
            const minColumnValue = this.getMinValueForNumericColumn(column);
            const maxColumnValue = this.getMaxValueForNumericColumn(column);
            maxValue = minColumnValue + (range.Max / 100) * (maxColumnValue - minColumnValue);
        }
        else if (range.Max === 'Col-Max') {
            const maxColumnValue = this.getMaxValueForNumericColumn(column);
            maxValue = maxColumnValue;
        }
        else {
            maxValue = range.Max;
        }
        return maxValue;
    }
    /**
     * Retrieves the ColumnComparison property, if there, from a Styled Column
     * @param styledColumn Styled Column to Add
     */
    getColumnComparisonForStyledColumn(styledColumn) {
        if (styledColumn.GradientStyle) {
            if (styledColumn.GradientStyle?.ColumnComparison) {
                return styledColumn.GradientStyle.ColumnComparison;
            }
        }
        if (styledColumn.PercentBarStyle) {
            if (styledColumn.PercentBarStyle?.ColumnComparison) {
                return styledColumn.PercentBarStyle.ColumnComparison;
            }
        }
        return undefined;
    }
    /**
     * Returns any ColumnIds referenced in a Column Comparison
     * @param columnComparision Column Comparison to check
     */
    getColumnIdsFromColumnComparison(columnComparison) {
        let returnValues = [];
        if (typeof columnComparison.MinValue === 'string') {
            let minIds = this.getDependentColumnIds(columnComparison.MinValue);
            if (ArrayExtensions_1.default.IsNotNullOrEmpty(minIds)) {
                returnValues.push(...minIds);
            }
        }
        if (typeof columnComparison.MaxValue === 'string') {
            let maxIds = this.getDependentColumnIds(columnComparison.MaxValue);
            if (ArrayExtensions_1.default.IsNotNullOrEmpty(maxIds)) {
                returnValues.push(...maxIds);
            }
        }
        return returnValues;
    }
    getDependentColumnIds(columnId) {
        if (this.getColumnApi().isCalculatedColumn(columnId)) {
            return this.getCalculatedColumnApi().internalApi.getReferencedColumnIdsForCalculatedColumnId(columnId);
        }
        else {
            return [columnId];
        }
    }
    /**
     * Checks if the styled column has a range with a relative value
     * @param styledColumn Styled Column to Add
     */
    hasStyledColumnRelativeCellRange(styledColumn) {
        let cellColorRange = null;
        let rangeValueType = 'Number';
        if (styledColumn.GradientStyle) {
            if (styledColumn.GradientStyle?.CellRanges) {
                cellColorRange = styledColumn.GradientStyle.CellRanges;
            }
            if (styledColumn.GradientStyle?.RangeValueType) {
                rangeValueType = styledColumn.GradientStyle.RangeValueType;
            }
        }
        if (styledColumn.PercentBarStyle) {
            if (styledColumn.PercentBarStyle?.CellRanges) {
                cellColorRange = styledColumn.PercentBarStyle.CellRanges;
            }
            if (styledColumn.PercentBarStyle?.RangeValueType) {
                rangeValueType = styledColumn.PercentBarStyle.RangeValueType;
            }
        }
        return ((rangeValueType === 'Percentage' ||
            cellColorRange?.some((cellColorRange) => {
                return cellColorRange.Min == 'Col-Min' || cellColorRange.Max == 'Col-Max';
            })) ??
            false);
    }
    getApplicableBadge(badgeStyle, context) {
        if (!badgeStyle.Badges.length) {
            return null;
        }
        // first that matches, sort last ones without predicate
        const badgesWithoutAll = [];
        const badgesWithAll = [];
        for (let badge of badgeStyle.Badges) {
            if (!badge.Predicate) {
                badgesWithAll.push(badge);
            }
            else {
                badgesWithoutAll.push(badge);
            }
        }
        for (let badge of badgesWithoutAll) {
            if (this.getPredicateApi().handlePredicate(badge.Predicate, context, false)) {
                return badge;
            }
        }
        const [firstBadgeWithAll] = badgesWithAll;
        return firstBadgeWithAll ?? null;
    }
    getBadgePredicateDefsForColumn(columnId) {
        const column = this.getColumnApi().getColumnWithColumnId(columnId);
        if (!column) {
            return undefined;
        }
        const scope = {
            ColumnIds: [column.columnId],
        };
        return this.getPredicateApi()
            .internalApi.getBadgeStylePredicateDefs(scope)
            .filter((predicate) => this.getColumnScopeApi().isColumnInScope(column, predicate.columnScope));
    }
}
exports.StyledColumnInternalApi = StyledColumnInternalApi;
