var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { adjust, assoc, difference, identity, __, gt, length, pathOr, chain, pipe, values } from 'ramda';
var INDEX_PATH_SEPARATOR = ',';
var indexPathToStringKey = function (indexPath) { return indexPath === null || indexPath === void 0 ? void 0 : indexPath.join(INDEX_PATH_SEPARATOR); };
var stringKeyToIndexPath = function (stringKey) { return stringKey.split(INDEX_PATH_SEPARATOR).map(Number); };
var isIndexPathSmaller = function (maxIndexPath, indexPath) {
    if (!indexPath || !maxIndexPath) {
        return true;
    }
    var minLength = Math.min(maxIndexPath.length, indexPath.length);
    for (var i = 0; i < minLength; i++) {
        if (indexPath[i] < maxIndexPath[i]) {
            return true;
        }
        else if (indexPath[i] > maxIndexPath[i]) {
            return false;
        }
    }
    return indexPath.length < maxIndexPath.length;
};
var isIndexPathOnSameLevel = function (maxIndexPath, indexPath) {
    if (!indexPath || !maxIndexPath) {
        return false;
    }
    var maxIndexPathLength = maxIndexPath.length;
    var isEqual = maxIndexPath.length === indexPath.length && maxIndexPath.every(function (value, index) { return value === indexPath[index]; });
    var isLeftEqual = maxIndexPath.every(function (value, index) { return value === indexPath[index]; });
    var isRightEqual = indexPath.slice(maxIndexPathLength).every(function (value) { return value === 0; });
    return isEqual || (isLeftEqual && isRightEqual);
};
var getBaseIndexStartsAt = function (rowValue) {
    for (var _i = 0, _a = Object.entries(rowValue); _i < _a.length; _i++) {
        var _b = _a[_i], columnId = _b[0], subcells = _b[1];
        if (columnId.startsWith('attributes.')) {
            var columnAttributes = columnId.split('.').slice(1);
            if (Array.isArray(subcells)) {
                for (var _c = 0, subcells_1 = subcells; _c < subcells_1.length; _c++) {
                    var subcell = subcells_1[_c];
                    if (subcell.nestedKey) {
                        var cellAttributes = subcell.nestedKey.split('.').filter(function (part) { return !isFinite(part); });
                        var diff = difference(cellAttributes, columnAttributes);
                        return diff.length;
                    }
                }
            }
        }
    }
    return 0;
};
var getMaxIndexPath = function (maxValuesCount, sortedSubcellValueGroups, baseIndexStartsAt) {
    var maxCount = 0;
    var baseCount = 0;
    var previousLevel = 0;
    var previousBaseIndex = 0;
    var maxIndexPathValuesCount = Infinity;
    var maxIndexPath = null;
    for (var _i = 0, sortedSubcellValueGroups_1 = sortedSubcellValueGroups; _i < sortedSubcellValueGroups_1.length; _i++) {
        var _a = sortedSubcellValueGroups_1[_i], indexPathKey = _a[0], visibleValuesCount = _a[1];
        var currentIndexPath = stringKeyToIndexPath(indexPathKey);
        var currentLevel = currentIndexPath.length;
        var currentBaseIndex = currentIndexPath[baseIndexStartsAt] || 0;
        var remainingCount = maxValuesCount - baseCount - maxCount;
        if (currentBaseIndex !== previousBaseIndex) {
            baseCount += maxCount;
            previousBaseIndex = currentBaseIndex;
            maxCount = 0;
        }
        if (currentLevel > previousLevel) {
            maxCount = Math.max(maxCount, Math.min(visibleValuesCount, maxValuesCount - baseCount));
        }
        else {
            maxCount += Math.min(visibleValuesCount, remainingCount);
        }
        if (maxCount + baseCount === maxValuesCount) {
            maxIndexPath = currentIndexPath;
            maxIndexPathValuesCount = currentLevel > previousLevel ? maxValuesCount - baseCount : remainingCount;
            break;
        }
        previousLevel = currentLevel;
    }
    return { maxIndexPath: maxIndexPath, maxIndexPathValuesCount: maxIndexPathValuesCount };
};
var sortIndexPaths = function (indexPathA, indexPathB) {
    var _a, _b;
    var numbersA = stringKeyToIndexPath(indexPathA);
    var numbersB = stringKeyToIndexPath(indexPathB);
    for (var i = 0; i < Math.max(numbersA.length, numbersB.length); i++) {
        var valA = (_a = numbersA[i]) !== null && _a !== void 0 ? _a : -1;
        var valB = (_b = numbersB[i]) !== null && _b !== void 0 ? _b : -1;
        if (valA !== valB)
            return valA - valB;
    }
    return 0;
};
var getSubcellValuesGroup = function (rowValue) {
    var subcellValueGroups = {};
    Object.values(rowValue).forEach(function (subcells) {
        return Array.isArray(subcells) &&
            subcells.forEach(function (subcell, i) {
                var indexPathKey = indexPathToStringKey(subcell.indexPath) || i;
                subcellValueGroups[indexPathKey] = Math.max(subcellValueGroups[indexPathKey] || 0, subcell.values.length);
            });
    });
    return Object.entries(subcellValueGroups).sort(function (_a, _b) {
        var indexPathKeyA = _a[0];
        var indexPathKeyB = _b[0];
        return sortIndexPaths(indexPathKeyA, indexPathKeyB);
    });
};
var processSubcell = function (subcell, maxIndexPath, maxIndexPathValuesCount) {
    var values = subcell.values, indexPath = subcell.indexPath, rest = __rest(subcell, ["values", "indexPath"]);
    var isPathSmaller = isIndexPathSmaller(maxIndexPath, indexPath);
    var isPathOnSameLevel = isIndexPathOnSameLevel(maxIndexPath, indexPath);
    var allowedCount = 0;
    if (isPathSmaller) {
        allowedCount = values.length;
    }
    else if (isPathOnSameLevel) {
        allowedCount = maxIndexPathValuesCount;
    }
    var visibleValues = values.slice(0, allowedCount);
    var hiddenSubcellValues = values.slice(allowedCount);
    var processedSubcell = __assign(__assign(__assign({}, rest), (indexPath ? { indexPath: indexPath } : {})), { values: visibleValues });
    var shouldIncludeSubcell = isPathSmaller || isPathOnSameLevel;
    return {
        processedSubcell: shouldIncludeSubcell ? processedSubcell : null,
        hiddenSubcellValues: hiddenSubcellValues
    };
};
var processAllSubcells = function (subcells, maxIndexPath, maxIndexPathValuesCount, columnHiddenValues) {
    var processedSubcells = subcells.map(function (subcell) {
        var _a = processSubcell(subcell, maxIndexPath, maxIndexPathValuesCount), processedSubcell = _a.processedSubcell, hiddenSubcellValues = _a.hiddenSubcellValues;
        if (hiddenSubcellValues.length) {
            columnHiddenValues.push.apply(columnHiddenValues, hiddenSubcellValues);
        }
        return processedSubcell;
    });
    return processedSubcells.filter(identity);
};
var applyCompactValuesCountConstraintForEntity = function (maxValuesCount, rowValue) {
    var sortedSubcellValueGroups = getSubcellValuesGroup(rowValue);
    var baseIndexStartsAt = getBaseIndexStartsAt(rowValue);
    var _a = getMaxIndexPath(maxValuesCount, sortedSubcellValueGroups, baseIndexStartsAt), maxIndexPath = _a.maxIndexPath, maxIndexPathValuesCount = _a.maxIndexPathValuesCount;
    var rowValueWithConstraints = Object.entries(rowValue).reduce(function (acc, _a) {
        var columnId = _a[0], subcells = _a[1];
        var columnHiddenValues = [];
        var processedSubcells = Array.isArray(subcells)
            ? processAllSubcells(subcells, maxIndexPath, maxIndexPathValuesCount, columnHiddenValues)
            : subcells;
        acc[columnId] = adjust(0, assoc('hiddenValues', columnHiddenValues), processedSubcells);
        return acc;
    }, {});
    return rowValueWithConstraints;
};
var applyCompactValuesCountConstraint = function (maxValuesCount) { return function (rowValue) {
    if (maxValuesCount === Infinity) {
        return rowValue;
    }
    return applyCompactValuesCountConstraintForEntity(maxValuesCount, rowValue);
}; };
var getHasHiddenAttributes = pipe(values, chain(identity), chain(pathOr([], ['hiddenValues'])), length, gt(__, 0));
export { applyCompactValuesCountConstraint, getHasHiddenAttributes };
