"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildSortedColumnStateForLayout = void 0;
const GeneralConstants_1 = require("../Utilities/Constants/GeneralConstants");
const ColumnInternalApi_1 = require("../Api/Internal/ColumnInternalApi");
const ColumnApiImpl_1 = require("../Api/Implementation/ColumnApiImpl");
const sortColumnStateForVisibleColumns_1 = require("./sortColumnStateForVisibleColumns");
function buildSortedColumnStateForLayout(params) {
    const { columnState, layout, groupDisplayType } = params;
    let visibleColumnList = [...layout.Columns];
    const multipleGroupColumns = groupDisplayType === 'multipleColumns';
    const singleGroupColumn = !multipleGroupColumns;
    const rowGroupedColumnsIndexes = {};
    let generatedRowGroupColumnsIds = [];
    // here we make sure the visibleColumnList includes all the generated group columns
    if (layout.RowGroupedColumns) {
        layout.RowGroupedColumns.forEach((colId, index) => {
            rowGroupedColumnsIndexes[colId] = index;
            rowGroupedColumnsIndexes[(0, ColumnInternalApi_1.getAutoRowGroupColumnIdFor)(colId)] = index;
        });
        // if the layout does not include the grouped columns,
        // make sure we add the grouped columns to the visible column list
        // at the start of the list
        if (singleGroupColumn) {
            if (!visibleColumnList.includes(GeneralConstants_1.AG_GRID_GROUPED_COLUMN)) {
                visibleColumnList = [GeneralConstants_1.AG_GRID_GROUPED_COLUMN, ...visibleColumnList];
            }
            generatedRowGroupColumnsIds.push(GeneralConstants_1.AG_GRID_GROUPED_COLUMN);
        }
        else {
            let missingGroupColumns = 0;
            [...layout.RowGroupedColumns].reverse().forEach((colId) => {
                const groupColId = (0, ColumnInternalApi_1.getAutoRowGroupColumnIdFor)(colId);
                if (!visibleColumnList.includes(groupColId)) {
                    visibleColumnList = [groupColId, ...visibleColumnList];
                    missingGroupColumns++;
                }
                generatedRowGroupColumnsIds = [groupColId, ...generatedRowGroupColumnsIds];
            });
            // now we need to sort the visibleColumnList to contain the group columns
            // in the correct order
            // but we only need to do this if the layout.Columns list missed some of the
            // group columns, but not all of them. if all were missing, we already
            // inserted them at the start of the list
            if (missingGroupColumns && missingGroupColumns < layout.RowGroupedColumns.length) {
                visibleColumnList.sort((colId1, colId2) => {
                    const isRowGroup1 = (0, ColumnApiImpl_1.isAutoRowGroupColumn)(colId1);
                    const isRowGroup2 = (0, ColumnApiImpl_1.isAutoRowGroupColumn)(colId2);
                    if (isRowGroup1 && isRowGroup2) {
                        return rowGroupedColumnsIndexes[colId1] - rowGroupedColumnsIndexes[colId2];
                    }
                    return 0;
                });
            }
        }
    }
    const visibleColumnsIndexes = visibleColumnList.reduce((acc, colId, index) => {
        acc[colId] = index;
        return acc;
    }, {});
    const pivotMode = layout.EnablePivot;
    if (pivotMode) {
        // in pivot mode, we sort the Visible columns of the layout
        // to make sure the group cols are at the beginning
        const groupCols = visibleColumnList.filter(ColumnApiImpl_1.isAutoRowGroupColumn);
        visibleColumnList = visibleColumnList.filter((colId) => !(0, ColumnApiImpl_1.isAutoRowGroupColumn)(colId));
        visibleColumnList = [...groupCols, ...visibleColumnList];
    }
    // we're now ready to go over the columnState
    // we want as much as possible to keep the order of the columns
    // as they are in the column state.
    // if the order is different in the visibleColumns, we only move those columns around
    // if some columns in the columnState are not in the visibleColumns, we need to return them as hide: true
    // first step - keep the same order, but filter out old group columns
    // VERY IMPORTANT to only filter out OLD group columns, that is,
    // group columns that are not in the layout anymore
    // since we might have different group columns in the layout
    let newColumnState = [...columnState].filter((colState) => {
        const { colId } = colState;
        if ((0, ColumnApiImpl_1.isAutoRowGroupColumn)(colId) && rowGroupedColumnsIndexes[colId] == null) {
            return false;
        }
        return true;
    });
    // second step - keep the same order
    // but make sure the visibility is adjusted to reflect the
    // visible columns in the layout
    newColumnState = newColumnState.map((colState) => {
        const { colId } = colState;
        const visibleIndex = visibleColumnsIndexes[colId];
        if (visibleIndex == null) {
            return Object.assign(Object.assign({}, colState), { hide: true });
        }
        return Object.assign(Object.assign({}, colState), { hide: null });
    });
    // third step - correctly mark the columns that are grouped
    newColumnState = newColumnState.map((colState) => {
        const { colId } = colState;
        const groupIndex = rowGroupedColumnsIndexes[colId];
        if (groupIndex != null) {
            return Object.assign(Object.assign({}, colState), { rowGroup: true, rowGroupIndex: groupIndex });
        }
        return Object.assign(Object.assign({}, colState), { rowGroup: false, rowGroupIndex: null });
    });
    // fourth step - add the new group columns, if they are missing
    const columnStateIndexes = newColumnState.reduce((acc, colState, index) => {
        acc[colState.colId] = index;
        return acc;
    }, {});
    generatedRowGroupColumnsIds.reverse().forEach((rowGroupColId) => {
        if (columnStateIndexes[rowGroupColId] == null) {
            newColumnState = [
                {
                    colId: rowGroupColId,
                },
                ...newColumnState,
            ];
        }
    });
    // fitfth step - sort the column state to respect the order of the visible columns
    // we can't simply call sort in this case
    return (0, sortColumnStateForVisibleColumns_1.sortColumnStateForVisibleColumns)(newColumnState, visibleColumnList);
}
exports.buildSortedColumnStateForLayout = buildSortedColumnStateForLayout;
