import { VersionUpgrade } from './VersionUpgrade';
import { ALL_ADAPTABLE_DATA_TYPES } from '../agGrid/agGridDataTypeDefinitions';
function transition_pre_20(layout) {
    const l = layout;
    if (l.Columns && !l.EnablePivot) {
        layout.TableColumns = l.Columns;
        delete l.Columns;
        delete layout.PivotColumns;
    }
    if (l.PinnedColumnsMap) {
        layout.ColumnPinning = { ...l.PinnedColumnsMap };
        delete l.PinnedColumnsMap;
    }
    if (l.ColumnHeadersMap) {
        layout.ColumnHeaders = l.ColumnHeadersMap;
        delete l.ColumnHeadersMap;
    }
    if (l.ColumnWidthMap) {
        //@ts-ignore
        layout.ColumnWidths = l.ColumnWidthMap;
        delete l.ColumnWidthMap;
    }
    if (l.EnablePivot) {
        layout.PivotColumns = l.PivotColumns || [];
        delete l.Columns;
        delete layout.TableColumns;
        delete l.EnablePivot;
        if (l.AggregationColumns) {
            layout.PivotAggregationColumns = (Object.entries(l.AggregationColumns) || []).map(([ColumnId, AggFunc]) => {
                return {
                    ColumnId,
                    AggFunc,
                };
            });
            delete layout.TableAggregationColumns;
            delete l.AggregationColumns;
        }
        if (l.RowGroupedColumns) {
            layout.PivotGroupedColumns = l.RowGroupedColumns;
            delete l.RowGroupedColumns;
        }
    }
    else {
        if (l.AggregationColumns && !Array.isArray(l.AggregationColumns)) {
            const oldAggs = l.AggregationColumns || {};
            const newAggs = Object.entries(oldAggs).map(([ColumnId, AggFunc]) => ({
                ColumnId,
                AggFunc,
            }));
            layout.TableAggregationColumns = newAggs;
            delete l.AggregationColumns;
        }
    }
    if (l.ExpandedRowGroupValues) {
        layout.RowGroupValues = {
            RowGroupDefaultBehavior: 'collapsed',
            ExceptionGroupKeys: l.ExpandedRowGroupValues,
        };
        delete l.ExpandedRowGroupValues;
    }
    if (Array.isArray(l.ColumnFilters)) {
        layout.ColumnFilters = l.ColumnFilters.map((columnFilter) => {
            const filter = {
                ...columnFilter,
            };
            // version 19 had a single predicate, while version 20 has an array of predicates
            // @ts-ignore
            if (filter.Predicate) {
                // @ts-ignore
                filter.Predicates = [filter.Predicate];
                // @ts-ignore
                delete filter.Predicate;
            }
            if (!Array.isArray(filter.Predicates)) {
                filter.Predicates = [];
            }
            filter.Predicates = filter.Predicates.map((p) => {
                // the following predicate ids were renamed:
                // Values -> In
                if (p.PredicateId === 'Values') {
                    p = { ...p };
                    p.PredicateId = 'In';
                }
                // ExcludeValues -> NotIn
                if (p.PredicateId === 'ExcludeValues') {
                    p = { ...p };
                    p.PredicateId = 'NotIn';
                }
                return p;
            });
            return filter;
        });
    }
    return layout;
}
function hasUpToDateDataType(dataType) {
    return ALL_ADAPTABLE_DATA_TYPES.includes(dataType);
}
export function mapOldTypeToDataType(previousType) {
    if (ALL_ADAPTABLE_DATA_TYPES.includes(previousType)) {
        return previousType;
    }
    switch (previousType) {
        case 'abColDefBoolean':
        case 'Boolean':
            return 'boolean';
        case 'abColDefDate':
        case 'Date':
            return 'date';
        case 'abColDefNumber':
        case 'Number':
            return 'number';
        case 'abColDefString':
        case 'String':
            return 'text';
        case 'abColDefObject':
        case 'Object':
            return 'object';
        case 'abColDefStringArray':
        case 'StringArray':
            return 'textArray';
        case 'abColDefNumberArray':
        case 'NumberArray':
            return 'numberArray';
        case 'abColDefTupleNumberArray':
        case 'TupleNumberArray':
            return 'tupleArray';
        case 'abColDefObjectNumberArray':
        case 'ObjectNumberArray':
            return 'objectArray';
        default:
            return 'unknown';
    }
}
export class VersionUpgrade20 extends VersionUpgrade {
    migrateState(state) {
        this.migrateLayoutState(state);
        this.migrateColTypeToDataType(state);
        this.migrateSparklineState(state);
        return state;
    }
    migrateLayoutState(state) {
        const layoutState = state.Layout;
        if (layoutState && layoutState.Layouts) {
            layoutState.Layouts = layoutState.Layouts.map((layout) => {
                return transition_pre_20(layout);
            });
        }
        return state;
    }
    migrateColTypeToDataType(state) {
        this.logger.info(`Converting previous column types to new data types`);
        // Calculated Column DataType
        const calculatedColumnState = state.CalculatedColumn;
        if (calculatedColumnState && calculatedColumnState.CalculatedColumns) {
            calculatedColumnState.CalculatedColumns.forEach((cc) => {
                if (cc.CalculatedColumnSettings?.DataType) {
                    if (hasUpToDateDataType(cc.CalculatedColumnSettings.DataType)) {
                        return;
                    }
                    const newDataType = mapOldTypeToDataType(cc.CalculatedColumnSettings.DataType);
                    if (newDataType === 'unknown') {
                        this.logger.warn(`Calculated Column ${cc.ColumnId} has an unknown DataType: ${cc.CalculatedColumnSettings.DataType}`);
                    }
                    else {
                        cc.CalculatedColumnSettings.DataType = newDataType;
                    }
                }
            });
        }
        // FreeText Column DataType
        const freeTextColumnState = state.FreeTextColumn;
        if (freeTextColumnState && freeTextColumnState.FreeTextColumns) {
            freeTextColumnState.FreeTextColumns.forEach((fc) => {
                if (fc.FreeTextColumnSettings?.DataType) {
                    if (hasUpToDateDataType(fc.FreeTextColumnSettings.DataType)) {
                        return;
                    }
                    const newDataType = mapOldTypeToDataType(fc.FreeTextColumnSettings.DataType);
                    if (newDataType === 'unknown') {
                        this.logger.warn(`FreeText Column ${fc.ColumnId} has an unknown DataType: ${fc.FreeTextColumnSettings.DataType}`);
                    }
                    else {
                        fc.FreeTextColumnSettings.DataType = newDataType;
                    }
                }
            });
        }
    }
    migrateSparklineState(state) {
        this.logger.info(`Migration of Sparkline State`);
        const sparklineState = state.StyledColumn;
        if (sparklineState && sparklineState.StyledColumns) {
            sparklineState.StyledColumns.forEach((styledColumn) => {
                // @ts-ignore renamed 'SparkLineStyle' to 'SparklineStyle'
                if (styledColumn.SparkLineStyle == undefined) {
                    return;
                }
                // @ts-ignore renamed 'SparkLineStyle' to 'SparklineStyle'
                // @ts-ignore
                styledColumn.SparklineStyle = styledColumn.SparkLineStyle;
                // @ts-ignore
                delete styledColumn.SparkLineStyle;
                // @ts-ignore the previous type was "column"
                if (styledColumn.SparklineStyle?.options?.type === 'column') {
                    // @ts-ignore the previous type was "column"
                    styledColumn.SparklineStyle.options.type = 'bar';
                    styledColumn.SparklineStyle.options.direction = 'vertical';
                }
                if (styledColumn.SparklineStyle?.options?.type === 'bar') {
                    styledColumn.SparklineStyle.options.direction = 'horizontal';
                }
                if (styledColumn.SparklineStyle?.options?.line) {
                    const previousLineOpts = (styledColumn.SparklineStyle?.options).line;
                    styledColumn.SparklineStyle.options.stroke = previousLineOpts.stroke;
                    styledColumn.SparklineStyle.options.strokeWidth = previousLineOpts.strokeWidth;
                    delete styledColumn.SparklineStyle.options.line;
                }
                if (styledColumn.SparklineStyle?.options?.axis &&
                    styledColumn.SparklineStyle?.options?.axis?.type == undefined) {
                    styledColumn.SparklineStyle.options.axis.type = 'category';
                }
                const obsoleteHighlightStyle = styledColumn.SparklineStyle?.options
                    ?.highlightStyle;
                if (obsoleteHighlightStyle) {
                    const obsoleteKeys = ['fill', 'stroke', 'strokeWidth'];
                    obsoleteKeys.forEach((obsoleteKey) => {
                        if (
                        // @ts-ignore
                        obsoleteHighlightStyle?.[obsoleteKey] != undefined) {
                            const itemHighlightStyle = obsoleteHighlightStyle.item ?? {};
                            // @ts-ignore
                            itemHighlightStyle[obsoleteKey] = obsoleteHighlightStyle?.[obsoleteKey];
                            // @ts-ignore
                            delete styledColumn.SparklineStyle.options.highlightStyle[obsoleteKey];
                        }
                    });
                }
                if ((styledColumn.SparklineStyle?.options).paddingInner != undefined) {
                    const axisOpts = (styledColumn.SparklineStyle.options.axis ?? {
                        type: 'category',
                    });
                    axisOpts.paddingInner = (styledColumn.SparklineStyle?.options).paddingInner;
                    delete (styledColumn.SparklineStyle?.options).paddingInner;
                }
                if ((styledColumn.SparklineStyle?.options).paddingOuter != undefined) {
                    const axisOpts = (styledColumn.SparklineStyle.options.axis ?? {
                        type: 'category',
                    });
                    axisOpts.paddingOuter = (styledColumn.SparklineStyle?.options).paddingOuter;
                    delete (styledColumn.SparklineStyle?.options).paddingOuter;
                }
                if ((styledColumn.SparklineStyle?.options).marker != undefined) {
                    (styledColumn.SparklineStyle?.options).marker.enabled = true;
                }
            });
        }
    }
}
