/*!
 * Built by Revolist OU ❤️
 */
import isArray from "lodash/isArray";
import reduce from "lodash/reduce";
import { columnTypes } from "../store/index";
export function getCellData(val) {
    if (typeof val === 'undefined' || val === null) {
        return '';
    }
    return val;
}
export function getCellRaw(model = {}, column) {
    if (!column) {
        return;
    }
    if (column.cellParser) {
        return column.cellParser(model, column);
    }
    return model[column.prop];
}
export function getCellDataParsed(model, column) {
    return getCellData(getCellRaw(model, column));
}
/**
 * Get column type from column data
 */
export function getColumnType(rgCol) {
    if (rgCol.pin) {
        return rgCol.pin;
    }
    return 'rgCol';
}
export function getColumnSizes(cols) {
    const res = {};
    for (const [i, c] of cols.entries()) {
        if (c.size) {
            res[i] = c.size;
        }
    }
    return res;
}
/**
 * Check if column is grouping column
 */
export function isColGrouping(colData) {
    return !!colData.children;
}
/**
 * This function is used to create a collection of columns.
 */
export function getColumns(columns, level = 0, types, resFromRoot) {
    const collection = {
        // columns as they are in stores per type
        columns: {
            rgCol: [],
            colPinStart: [],
            colPinEnd: [],
        },
        // columns indexed by prop for quick access
        columnByProp: {},
        // column grouping
        columnGrouping: {
            rgCol: [],
            colPinStart: [],
            colPinEnd: [],
        },
        // sorting
        sort: {},
        // max depth level for column grouping
        maxLevel: level,
    };
    return reduce(columns, (res, colData) => {
        var _a;
        // Grouped column
        if (isColGrouping(colData)) {
            res = gatherGroup(res, colData, getColumns(colData.children, level + 1, types, res), resFromRoot === null || resFromRoot === void 0 ? void 0 : resFromRoot.columns, level);
            return res;
        }
        // Column type
        const columnDefinitionFromType = colData.columnType && (types === null || types === void 0 ? void 0 : types[colData.columnType]);
        // Regular column
        const regularColumn = Object.assign(Object.assign({}, columnDefinitionFromType), colData);
        // Regular column, no Pin
        if (!regularColumn.pin) {
            res.columns.rgCol.push(regularColumn);
            // Pin
        }
        else {
            res.columns[regularColumn.pin].push(regularColumn);
        }
        if (regularColumn.order) {
            res.sort[regularColumn.prop] = regularColumn;
        }
        // it's possible that some columns have same prop, but better to avoid it
        if (!res.columnByProp[regularColumn.prop]) {
            res.columnByProp[regularColumn.prop] = [];
        }
        res.columnByProp[regularColumn.prop].push(regularColumn);
        // trigger setup hook if present
        (_a = regularColumn.beforeSetup) === null || _a === void 0 ? void 0 : _a.call(regularColumn, regularColumn);
        return res;
    }, collection);
}
export function gatherGroup(res, colData, collection, existingColumnsByType, level = 0) {
    // group template
    const group = Object.assign(Object.assign({}, colData), { level, indexes: [] });
    // check columns for update
    columnTypes.forEach(type => {
        const resultItem = res.columns[type];
        const collectionItem = collection.columns[type];
        // if column data
        if (isArray(resultItem) && isArray(collectionItem)) {
            // fill grouping
            const itemLength = collectionItem.length;
            if (itemLength) {
                const columnLength = [...((existingColumnsByType === null || existingColumnsByType === void 0 ? void 0 : existingColumnsByType[type]) || []), ...resultItem].length;
                // fill columns
                resultItem.push(...collectionItem);
                // fill indexes per each viewport
                res.columnGrouping[type].push(Object.assign(Object.assign({}, group), { indexes: Array(itemLength).fill(columnLength).map((v, i) => v + i) }));
            }
        }
    });
    // merge column groupings
    for (let k in collection.columnGrouping) {
        const key = k;
        const collectionItem = collection.columnGrouping[key];
        const delta = ((existingColumnsByType === null || existingColumnsByType === void 0 ? void 0 : existingColumnsByType[key]) || []).length;
        const rebasedItem = delta > 0
            ? collectionItem.map(group => (Object.assign(Object.assign({}, group), { indexes: group.indexes.map(i => i + delta) })))
            : collectionItem;
        res.columnGrouping[key].push(...rebasedItem);
    }
    res.maxLevel = Math.max(res.maxLevel, collection.maxLevel);
    res.sort = Object.assign(Object.assign({}, res.sort), collection.sort);
    res.columnByProp = Object.assign(Object.assign({}, res.columnByProp), collection.columnByProp);
    return res;
}
function findColumn(columns, prop) {
    for (const c of columns) {
        if (isColGrouping(c)) {
            const found = findColumn(c.children, prop);
            if (found) {
                return found;
            }
        }
        else if (c.prop === prop) {
            return c;
        }
    }
    return undefined;
}
export function getColumnByProp(columns, prop) {
    return findColumn(columns, prop);
}
