/*!
 * Built by Revolist OU ❤️
 */
import reduce from "lodash/reduce";
import { columnTypes, DataStore, getSourceItem, getSourceItemVirtualIndexByProp, setSourceByPhysicalIndex, setSourceByVirtualIndex, } from "../store/index";
import { getColumnType } from "../utils/column.utils";
export default class ColumnDataProvider {
    get stores() {
        return this.dataSources;
    }
    constructor() {
        this.collection = null;
        this.dataSources = columnTypes.reduce((sources, k) => {
            sources[k] = new DataStore(k);
            return sources;
        }, {});
    }
    column(c, type = 'rgCol') {
        return this.getColumn(c, type);
    }
    getColumn(virtualIndex, type) {
        return getSourceItem(this.dataSources[type].store, virtualIndex);
    }
    getRawColumns() {
        return reduce(this.dataSources, (result, item, type) => {
            result[type] = item.store.get('source');
            return result;
        }, {
            rgCol: [],
            colPinStart: [],
            colPinEnd: [],
        });
    }
    getColumns(type = 'all') {
        const columnsByType = this.getRawColumns();
        if (type !== 'all') {
            return columnsByType[type];
        }
        return columnTypes.reduce((r, t) => [...r, ...columnsByType[t]], []);
    }
    getColumnIndexByProp(prop, type) {
        return getSourceItemVirtualIndexByProp(this.dataSources[type].store, prop);
    }
    getColumnByProp(prop) {
        var _a;
        return (_a = this.collection) === null || _a === void 0 ? void 0 : _a.columnByProp[prop];
    }
    refreshByType(type) {
        this.dataSources[type].refresh();
    }
    /**
     * Main method to set columns
     */
    setColumns(data) {
        columnTypes.forEach(k => {
            // set columns data
            this.dataSources[k].updateData(data.columns[k], {
                // max depth level
                depth: data.maxLevel,
                // groups
                groups: data.columnGrouping[k].reduce((res, g) => {
                    if (!res[g.level]) {
                        res[g.level] = [];
                    }
                    res[g.level].push(g);
                    return res;
                }, {}),
            });
        });
        this.collection = data;
        return data;
    }
    /**
     * Used in plugins
     * Modify columns in store
     */
    updateColumns(updatedColumns) {
        // collect column by type and propert
        const columnByKey = updatedColumns.reduce((res, c) => {
            const type = getColumnType(c);
            if (!res[type]) {
                res[type] = {};
            }
            res[type][c.prop] = c;
            return res;
        }, {});
        // find indexes in source
        const colByIndex = {};
        for (const t in columnByKey) {
            if (!columnByKey.hasOwnProperty(t)) {
                continue;
            }
            const type = t;
            const colsToUpdate = columnByKey[type];
            const sourceItems = this.dataSources[type].store.get('source');
            colByIndex[type] = {};
            for (let i = 0; i < sourceItems.length; i++) {
                const column = sourceItems[i];
                const colToUpdateIfExists = colsToUpdate === null || colsToUpdate === void 0 ? void 0 : colsToUpdate[column.prop];
                // update column if exists in source
                if (colToUpdateIfExists) {
                    colByIndex[type][i] = colToUpdateIfExists;
                }
            }
        }
        for (const t in colByIndex) {
            if (!colByIndex.hasOwnProperty(t)) {
                continue;
            }
            const type = t;
            setSourceByPhysicalIndex(this.dataSources[type].store, colByIndex[type] || {});
        }
    }
    updateColumn(column, index) {
        const type = getColumnType(column);
        setSourceByVirtualIndex(this.dataSources[type].store, { [index]: column });
    }
}
