import { VersionUpgrade } from './VersionUpgrade';
import { removeAdaptableObjectPrimitivesInlineDeep } from '../Utilities/Helpers/AdaptableHelper';
export class VersionUpgrade22 extends VersionUpgrade {
    migrateState(state) {
        this.migrateFormatColumnState(state);
        this.migrateNamedObjectState(state);
        return state;
    }
    migrateNamedObjectState(state) {
        this.patchCustomSortName(state.CustomSort);
        this.patchFlashingCellName(state.FlashingCell);
        this.patchFormatColumnName(state.FormatColumn);
        this.patchPlusMinusNudgeName(state.PlusMinus);
        this.patchShortcutName(state.Shortcut);
        this.patchAlertName(state.Alert);
        this.patchScheduleName(state.Schedule);
    }
    // We have moved CellAlignment (renamed Alignment) from independent property into Style
    migrateFormatColumnState(state) {
        const formatColumnState = state.FormatColumn;
        if (formatColumnState && formatColumnState.FormatColumns) {
            formatColumnState.FormatColumns = formatColumnState.FormatColumns.map((formatColumn) => {
                //@ts-ignore
                if (formatColumn.CellAlignment) {
                    formatColumn.Style = {
                        ...formatColumn.Style,
                        //@ts-ignore
                        Alignment: formatColumn.CellAlignment,
                    };
                    //@ts-ignore
                    delete formatColumn.CellAlignment;
                }
                return formatColumn;
            });
        }
        return state;
    }
    patchCustomSortName(customSortState) {
        if (!customSortState) {
            return;
        }
        customSortState.CustomSorts?.forEach((customSort) => {
            if (!customSort.Name) {
                const sortedValues = (customSort.SortedValues || []).join();
                customSort.Name = `CustomSort-${customSort.ColumnId}-${this.hashStrings(['CustomSort', customSort.ColumnId, sortedValues])}`;
            }
        });
    }
    patchFlashingCellName(flashingCellState) {
        if (!flashingCellState) {
            return;
        }
        flashingCellState.FlashingCellDefinitions?.forEach((flashingCell) => {
            if (!flashingCell.Name) {
                const scopeStr = this.scopeToString(flashingCell.Scope);
                const ruleStr = flashingCell.Rule?.BooleanExpression || '';
                flashingCell.Name = `FlashingCell-${this.hashStrings(['FlashingCell', scopeStr, ruleStr])}`;
            }
        });
    }
    patchFormatColumnName(formatColumnState) {
        if (!formatColumnState) {
            return;
        }
        formatColumnState.FormatColumns?.forEach((formatColumn) => {
            if (!formatColumn.Name) {
                const scopeStr = this.scopeToString(formatColumn.Scope);
                const styleStr = this.stringifyWithoutMetadata(formatColumn.Style);
                formatColumn.Name = `FormatColumn-${this.hashStrings(['FormatColumn', scopeStr, styleStr])}`;
            }
        });
    }
    patchPlusMinusNudgeName(plusMinusState) {
        if (!plusMinusState) {
            return;
        }
        plusMinusState.PlusMinusNudges?.forEach((nudge) => {
            if (!nudge.Name) {
                const scopeStr = this.scopeToString(nudge.Scope);
                const nudgeValue = String(nudge.NudgeValue ?? '');
                nudge.Name = `PlusMinus-${this.hashStrings(['PlusMinus', scopeStr, nudgeValue])}`;
            }
        });
    }
    patchShortcutName(shortcutState) {
        if (!shortcutState) {
            return;
        }
        shortcutState.Shortcuts?.forEach((shortcut) => {
            if (!shortcut.Name) {
                const key = shortcut.ShortcutKey || '';
                const operation = shortcut.ShortcutOperation || '';
                const value = String(shortcut.ShortcutValue ?? '');
                shortcut.Name = `Shortcut-${key}-${this.hashStrings(['Shortcut', key, operation, value])}`;
            }
        });
    }
    patchAlertName(alertState) {
        if (!alertState) {
            return;
        }
        alertState.AlertDefinitions?.forEach((alert) => {
            if (!alert.Name) {
                const scopeStr = this.scopeToString(alert.Scope);
                const messageType = alert.MessageType || '';
                const ruleStr = this.stringifyWithoutMetadata(alert.Rule);
                alert.Name = `Alert-${messageType}-${this.hashStrings(['Alert', scopeStr, messageType, ruleStr])}`;
            }
        });
    }
    patchScheduleName(scheduleState) {
        if (!scheduleState) {
            return;
        }
        // Patch Reminder Schedules
        scheduleState.Reminders?.forEach((reminder) => {
            if (!reminder.Name) {
                const header = reminder.Header || '';
                const message = reminder.Message || '';
                reminder.Name = `Reminder-${this.hashStrings(['Reminder', header, message])}`;
            }
        });
        // Patch Report Schedules
        scheduleState.ReportSchedules?.forEach((report) => {
            if (!report.Name) {
                const reportName = report.ReportName || '';
                const format = report.ReportFormat || '';
                report.Name = `ReportSchedule-${this.hashStrings(['ReportSchedule', reportName, format])}`;
            }
        });
        // Patch IPushPull Schedules
        scheduleState.IPushPullSchedules?.forEach((ipp) => {
            if (!ipp.Name) {
                const reportName = ipp.IPushPullReport?.ReportName || '';
                const folder = ipp.IPushPullReport?.Folder || '';
                const page = ipp.IPushPullReport?.Page || '';
                ipp.Name = `IPushPullSchedule-${this.hashStrings(['IPushPullSchedule', reportName, folder, page])}`;
            }
        });
        // Patch OpenFin Schedules
        scheduleState.OpenFinSchedules?.forEach((openfin) => {
            if (!openfin.Name) {
                const reportName = openfin.OpenFinReport?.ReportName || '';
                openfin.Name = `OpenFinSchedule-${this.hashStrings(['OpenFinSchedule', reportName])}`;
            }
        });
    }
    scopeToString(scope) {
        if (!scope) {
            return '';
        }
        if ('All' in scope && scope.All) {
            return 'All';
        }
        if ('ColumnIds' in scope && scope.ColumnIds) {
            return scope.ColumnIds.join(',');
        }
        if ('DataTypes' in scope && scope.DataTypes) {
            return scope.DataTypes.join(',');
        }
        if ('ColumnTypes' in scope && scope.ColumnTypes) {
            return scope.ColumnTypes.join(',');
        }
        return '';
    }
    hashStrings(strings) {
        let hash = 0;
        for (const str of strings) {
            for (let i = 0; i < str.length; i++) {
                hash = (hash * 31 + str.charCodeAt(i)) % 9000;
            }
        }
        return hash + 1000;
    }
    /**
     * Stringifies an object after removing metadata properties (Uuid, Source, AdaptableVersion)
     * to ensure deterministic hashing regardless of generated values.
     */
    stringifyWithoutMetadata(obj) {
        if (!obj) {
            return '';
        }
        const cloned = structuredClone(obj);
        removeAdaptableObjectPrimitivesInlineDeep(cloned);
        return JSON.stringify(cloned);
    }
}
