import { LEGACY_RANK_DATA_TYPES, RANK_DATA_TYPES, rankDataMetaKey, type LegacyRankDataType, type RankDataType, } from '@sammo-ts/common'; export interface RankedGeneralState { id: number; nationId: number; experience: number; dedication: number; meta: unknown; } export interface PersistedRankRow { generalId: number; nationId: number; type: RankDataType; value: number; } const asRecord = (value: unknown): Record => typeof value === 'object' && value !== null && !Array.isArray(value) ? { ...(value as Record) } : {}; const toLegacyDatabaseInt = (value: number): number => { if (!Number.isFinite(value)) { return 0; } return value >= 0 ? Math.floor(value + 0.5) : Math.ceil(value - 0.5); }; const readMetaNumber = (meta: Record, key: string): number => { const value = meta[key]; if (typeof value === 'number' && Number.isFinite(value)) { return toLegacyDatabaseInt(value); } if (typeof value === 'string') { const parsed = Number(value); return Number.isFinite(parsed) ? toLegacyDatabaseInt(parsed) : 0; } return 0; }; export const rankMetaKey = rankDataMetaKey; export const buildPersistedRankRows = (general: RankedGeneralState): PersistedRankRow[] => { const meta = asRecord(general.meta); return RANK_DATA_TYPES.map((type) => { const value = type === 'experience' ? toLegacyDatabaseInt(general.experience) : type === 'dedication' ? toLegacyDatabaseInt(general.dedication) : readMetaNumber(meta, rankMetaKey(type)); return { generalId: general.id, nationId: general.nationId, type, value, }; }); }; export const buildLegacyComparableRankRows = ( general: RankedGeneralState ): Array => { const legacyTypes = new Set(LEGACY_RANK_DATA_TYPES); return buildPersistedRankRows(general).filter( (row): row is PersistedRankRow & { type: LegacyRankDataType } => legacyTypes.has(row.type) ); }; export const applyPersistedRankRowsToMeta = ( rawMeta: Record, rows: ReadonlyArray<{ type: string; value: number }> ): void => { const supportedTypes = new Set(RANK_DATA_TYPES); for (const row of rows) { if (row.type === 'experience' || row.type === 'dedication' || !supportedTypes.has(row.type)) { continue; } rawMeta[rankMetaKey(row.type as RankDataType)] = row.value; } };