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);
};
import { __, add, adjust, always, assoc, chain, evolve, gt, identity, isEmpty, isNil, length, map, mapObjIndexed, max, pathOr, pipe, pluck, propEq, propOr, reduce, reject, slice, uniq, unless, values } from 'ramda';
import { wrapInArrayIfNeeded } from '@reltio/mdm-sdk';
import { DefaultCellValueRenderer } from '../../DefaultCellValueRenderer';
import { calcRowSpansForNestedKeys, flattenNestedColumnValues, getNestedKeyForNestedColumnCell, TOTAL_ROW_SPAN_KEY } from './nestedHelpers';
var applyCellRendererToColumnCells = function (columnsData, renderRowCell, rowIndex, rowValue) { return function (cells, columnId) {
    var columnIndex = columnsData.findIndex(propEq('id', columnId));
    var columnData = columnsData[columnIndex];
    var _a = columnsData[columnIndex].rowCellValueRenderer, CellValueRenderer = _a === void 0 ? DefaultCellValueRenderer : _a;
    return cells.map(function (cell, cellIndex) { return (__assign(__assign({}, cell), { values: renderRowCell({
            columnIndex: columnIndex,
            columnData: columnData,
            rowIndex: rowIndex,
            rowValue: rowValue,
            cellIndex: cellIndex,
            cell: cell,
            CellValueRenderer: CellValueRenderer
        }) })); });
}; };
var applyCellRenderer = pipe(applyCellRendererToColumnCells, mapObjIndexed);
var calcHeightForColumnCells = function (columnsData, getRowCellHeight, rowIndex, rowValue) { return function (cells, columnId) {
    var columnIndex = columnsData.findIndex(propEq('id', columnId));
    var columnData = columnsData[columnIndex];
    return cells.map(function (cell, cellIndex) { return (__assign(__assign({}, cell), { height: getRowCellHeight({ columnIndex: columnIndex, columnData: columnData, rowIndex: rowIndex, rowValue: rowValue, cellIndex: cellIndex, cell: cell }) })); });
}; };
var calcHeights = function (columnsData, getRowCellHeight, rowIndex, rowValue) { return function (rowData) {
    return getRowCellHeight
        ? mapObjIndexed(calcHeightForColumnCells(columnsData, getRowCellHeight, rowIndex, rowValue), rowData)
        : rowData;
}; };
var addRowSpansToColumnCells = function (rowSpansData) {
    return map(function (cell) { return (__assign(__assign({}, cell), { rowSpan: rowSpansData[cell.nestedKey || TOTAL_ROW_SPAN_KEY] })); });
};
var getNestedKeysFromRowCells = pipe(chain(pluck('nestedKey')), reject(isNil), uniq);
var calcRowSpansData = pipe(values, getNestedKeysFromRowCells, calcRowSpansForNestedKeys);
var calcRowSpans = function (rowData) {
    var rowSpansData = calcRowSpansData(rowData);
    return isEmpty(rowSpansData) ? rowData : map(addRowSpansToColumnCells(rowSpansData), rowData);
};
var calcNestedKeys = function (columnNestedPath) {
    return map(function (cell) { return (__assign(__assign({}, cell), { nestedKey: getNestedKeyForNestedColumnCell(columnNestedPath, cell) })); });
};
var parseNestedColumnValues = function (columnNestedPath, nestedValues) {
    return pipe(flattenNestedColumnValues, calcNestedKeys(columnNestedPath))(nestedValues);
};
var getCellValues = function (columnNestedPath, columnValues) {
    return columnNestedPath && !isEmpty(columnValues)
        ? parseNestedColumnValues(columnNestedPath, columnValues)
        : [{ values: wrapInArrayIfNeeded(columnValues) }];
};
var buildRowValues = function (rowValue) {
    return reduce(function (acc, _a) {
        var id = _a.id, nestedPath = _a.nestedPath;
        return assoc(id, getCellValues(nestedPath, rowValue[id]), acc);
    }, {});
};
var areNestedValuesExceedingLimit = function (maxValuesCount) {
    return function (_a) {
        var indexPath = _a.indexPath;
        return indexPath && indexPath.some(function (index) { return index > maxValuesCount - 1; });
    };
};
var getHiddenValues = function (rowValues, maxValuesCount) {
    if (maxValuesCount === void 0) { maxValuesCount = Infinity; }
    return rowValues.reduce(function (hiddenValues, _a) {
        var _b = _a.values, values = _b === void 0 ? [] : _b, indexPath = _a.indexPath;
        var newHiddenValues = areNestedValuesExceedingLimit(maxValuesCount)({ indexPath: indexPath })
            ? values
            : values.slice(maxValuesCount);
        return hiddenValues.concat(newHiddenValues);
    }, []);
};
var adjustFirstWithHiddenValues = function (maxValuesCount) {
    if (maxValuesCount === void 0) { maxValuesCount = Infinity; }
    return function (rowValues) {
        var hiddenValues = getHiddenValues(rowValues, maxValuesCount);
        return adjust(0, assoc('hiddenValues', hiddenValues), rowValues);
    };
};
var applyDefaultValuesCountConstraint = function (maxValuesCount) {
    return unless(function () { return maxValuesCount === Infinity; }, map(pipe(adjustFirstWithHiddenValues(maxValuesCount), reject(areNestedValuesExceedingLimit(maxValuesCount)), map(evolve({
        values: slice(0, maxValuesCount)
    })))));
};
var defaultGetIdFromRowValue = function (_, rowIndex) { return rowIndex; };
var getTableRowsData = function (rowValues, columnsData, renderRowCell, getRowCellHeight, getRowMaxValuesCount, getIdFromRowValue, applyMaxValuesCountConstraint) {
    if (getRowMaxValuesCount === void 0) { getRowMaxValuesCount = always(Infinity); }
    if (getIdFromRowValue === void 0) { getIdFromRowValue = defaultGetIdFromRowValue; }
    applyMaxValuesCountConstraint = applyMaxValuesCountConstraint || applyDefaultValuesCountConstraint;
    return rowValues.map(function (rowValue, rowIndex) {
        return pipe(buildRowValues(rowValue), applyMaxValuesCountConstraint(getRowMaxValuesCount(rowIndex)), calcRowSpans, calcHeights(columnsData, getRowCellHeight, rowIndex, rowValue), applyCellRenderer(columnsData, renderRowCell, rowIndex, rowValue), function (val) { return ({ data: val, id: getIdFromRowValue(rowValue, rowIndex) }); })(columnsData);
    });
};
var calcMaxValuesCount = reduce(function (maxCount, cellValues) {
    var maxSubNestedValuesCount = pipe(chain(propOr([], 'indexPath')), map(add(1)), reduce(max, 0))(cellValues);
    var maxPlainValuesCount = pipe(pluck('values'), pluck('length'), reduce(max, 0))(cellValues);
    return Math.max(maxCount, maxSubNestedValuesCount, maxPlainValuesCount);
}, 0);
var getMaxRowValuesCount = function (columnsData, rowValue) {
    return pipe(buildRowValues(rowValue), values, calcMaxValuesCount)(columnsData);
};
var getHasHiddenAttributes = pipe(values, chain(identity), chain(pathOr([], ['hiddenValues'])), length, gt(__, 0));
var getIsRowCollapsibleFromMaxValuesCount = function (columnsData, rowValue, maxValuesCount, applyMaxValuesCountConstraint) {
    if (applyMaxValuesCountConstraint) {
        return pipe(buildRowValues(rowValue), applyMaxValuesCountConstraint(maxValuesCount), getHasHiddenAttributes)(columnsData);
    }
    return getMaxRowValuesCount(columnsData, rowValue) > maxValuesCount;
};
export { getTableRowsData, getMaxRowValuesCount, getIsRowCollapsibleFromMaxValuesCount };
