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 __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { __, addIndex, always, assoc, chain, curry, dropLast, groupBy, join, keys, length, omit, pickBy, pipe, propOr, reduce, split, sortBy, identity, sum, toPairs, unless, unnest, values, zip } from 'ramda';
var TOTAL_ROW_SPAN_KEY = 'total';
var NESTED_KEY_DELIMITER = '.';
var getSiblingSubRowsKeyBySubRowKey = pipe(split(NESTED_KEY_DELIMITER), dropLast(1), join(NESTED_KEY_DELIMITER));
var getParentRowKeyBySiblingsSubRowsKey = pipe(split(NESTED_KEY_DELIMITER), dropLast(1), join(NESTED_KEY_DELIMITER), unless(length, always(TOTAL_ROW_SPAN_KEY)));
var getParentRowKeyBySubRowKey = pipe(getSiblingSubRowsKeyBySubRowKey, getParentRowKeyBySiblingsSubRowsKey);
var getSameNestingDepthNestedKeys = function (rowSpanData, keyToBeMatched) {
    var parentKeyToBeMatched = getSiblingSubRowsKeyBySubRowKey(keyToBeMatched);
    return Object.keys(rowSpanData).filter(function (currentKey) {
        var currentParentKey = getParentRowKeyBySubRowKey(currentKey);
        return (currentParentKey === parentKeyToBeMatched ||
            (currentParentKey === TOTAL_ROW_SPAN_KEY && parentKeyToBeMatched === ''));
    });
};
var getRequiredRowSpan = function (rowSpanData, sameLevelNestedKeys, subRowKey, cellsWithExtraSpanAvailable) {
    var subcellIndex = subRowKey.split(NESTED_KEY_DELIMITER).pop();
    var minSpan = sameLevelNestedKeys
        .filter(function (key) { return key.split(NESTED_KEY_DELIMITER).pop() === subcellIndex; })
        .reduce(function (minSpan, key) {
        return cellsWithExtraSpanAvailable.includes(getSiblingSubRowsKeyBySubRowKey(key))
            ? minSpan
            : Math.min(minSpan, rowSpanData[key]);
    }, Infinity);
    return minSpan === Infinity ? rowSpanData[subRowKey] : Math.max(rowSpanData[subRowKey], minSpan);
};
var countParentSpanByAllSubRows = function (rowSpanData, siblingSubRowsKey) {
    return pipe(pickBy(function (_val, key) { return getSiblingSubRowsKeyBySubRowKey(key) === siblingSubRowsKey; }), values, sum)(rowSpanData);
};
var calcParentRowSpan = function (rowSpanData, subRowKey) {
    var parentKey = getParentRowKeyBySubRowKey(subRowKey);
    var currentParentSpan = propOr(0, parentKey, rowSpanData);
    var actualParentSpan = countParentSpanByAllSubRows(rowSpanData, getSiblingSubRowsKeyBySubRowKey(subRowKey));
    if (actualParentSpan > currentParentSpan) {
        var nextRowSpanData = assoc(parentKey, actualParentSpan, rowSpanData);
        return parentKey === TOTAL_ROW_SPAN_KEY ? nextRowSpanData : calcParentRowSpan(nextRowSpanData, parentKey);
    }
    else {
        return rowSpanData;
    }
};
var addNestedKey = function (rowSpanData, nestedKey) {
    var _a;
    return calcParentRowSpan(__assign(__assign({}, rowSpanData), (_a = {}, _a[nestedKey] = 1, _a)), nestedKey);
};
var validateRowSpans = function (rowSpanData) { return function (groups) {
    var cellsWithExtraSpanAvailable = [];
    for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
        var group = groups_1[_i];
        var siblingSubRowsKey = group[0];
        var parentKey = getParentRowKeyBySiblingsSubRowsKey(siblingSubRowsKey);
        var currentParentSpan = propOr(0, parentKey, rowSpanData);
        var actualParentSpan = countParentSpanByAllSubRows(rowSpanData, siblingSubRowsKey);
        if (currentParentSpan > actualParentSpan) {
            cellsWithExtraSpanAvailable.push(siblingSubRowsKey);
        }
    }
    return groups.reduce(function (rowSpanData, group) { return validateParentRowSpan(rowSpanData, group, cellsWithExtraSpanAvailable); }, rowSpanData);
}; };
var validateParentRowSpan = function (rowSpanData, _a, cellsWithExtraSpanAvailable) {
    var siblingSubRowsKey = _a[0], subRowsKeys = _a[1];
    var parentKey = getParentRowKeyBySiblingsSubRowsKey(siblingSubRowsKey);
    var currentParentSpan = propOr(0, parentKey, rowSpanData);
    var actualParentSpan = countParentSpanByAllSubRows(rowSpanData, siblingSubRowsKey);
    var spanDiff = currentParentSpan - actualParentSpan;
    if (spanDiff > 0) {
        var sameDepthNestedKeys_1 = getSameNestingDepthNestedKeys(rowSpanData, siblingSubRowsKey);
        var sumOfRequiredRowSpans_1 = 0;
        var correctedRowSpanData = subRowsKeys.reduce(function (acc, subRowKey) {
            var requiredRowSpan = getRequiredRowSpan(rowSpanData, sameDepthNestedKeys_1, subRowKey, cellsWithExtraSpanAvailable);
            acc[subRowKey] = requiredRowSpan;
            sumOfRequiredRowSpans_1 += requiredRowSpan;
            return acc;
        }, {});
        var newRowSpanData = __assign({}, rowSpanData);
        if (currentParentSpan >= sumOfRequiredRowSpans_1) {
            spanDiff = currentParentSpan - sumOfRequiredRowSpans_1;
            newRowSpanData = __assign(__assign({}, rowSpanData), correctedRowSpanData);
            if (spanDiff === 0)
                return newRowSpanData;
        }
        var lowestSubRowKey = "".concat(siblingSubRowsKey).concat(NESTED_KEY_DELIMITER).concat(subRowsKeys.length - 1);
        var lowestSubRowSpan = newRowSpanData[lowestSubRowKey];
        return assoc(lowestSubRowKey, lowestSubRowSpan + spanDiff, newRowSpanData);
    }
    else {
        return rowSpanData;
    }
};
var validateRowSpanData = function (rowSpanData) {
    return pipe(omit([TOTAL_ROW_SPAN_KEY]), keys, sortBy(identity), groupBy(getSiblingSubRowsKeyBySubRowKey), toPairs, validateRowSpans(rowSpanData))(rowSpanData);
};
var calcRowSpansForNestedKeys = pipe(sortBy(identity), reduce(addNestedKey, {}), validateRowSpanData);
var chainWithIndex = addIndex(chain);
var flattenNestedColumnValues = function (values, indexPath) {
    if (indexPath === void 0) { indexPath = []; }
    var head = values[0];
    return Array.isArray(head)
        ? chainWithIndex(function (value, index) { return flattenNestedColumnValues(value, __spreadArray(__spreadArray([], indexPath, true), [index], false)); }, values)
        : { indexPath: indexPath, values: values };
};
var getNestedKeyForNestedColumnCell = curry(function (columnNestedPath, cell) {
    return pipe(zip(__, cell.indexPath), unnest, join(NESTED_KEY_DELIMITER))(columnNestedPath);
});
export { calcRowSpansForNestedKeys, validateRowSpanData, TOTAL_ROW_SPAN_KEY, flattenNestedColumnValues, getSiblingSubRowsKeyBySubRowKey, getParentRowKeyBySiblingsSubRowsKey, getNestedKeyForNestedColumnCell };
