function isFiniteNumber(value) {
    return typeof value === 'number' && Number.isFinite(value);
}
function updatedAtOf(state) {
    if (!state)
        return null;
    return isFiniteNumber(state.stopMessageUpdatedAt) ? state.stopMessageUpdatedAt : null;
}
function lastUsedAtOf(state) {
    if (!state)
        return null;
    return isFiniteNumber(state.stopMessageLastUsedAt) ? state.stopMessageLastUsedAt : null;
}
function usedOf(state) {
    if (!state)
        return null;
    return isFiniteNumber(state.stopMessageUsed) ? state.stopMessageUsed : null;
}
function normalizeText(value) {
    return typeof value === 'string' ? value.trim() : '';
}
function sameStopMessageConfig(existing, persisted) {
    return normalizeText(existing.stopMessageText) === normalizeText(persisted.stopMessageText)
        && existing.stopMessageMaxRepeats === persisted.stopMessageMaxRepeats
        && normalizeText(existing.stopMessageStageMode) === normalizeText(persisted.stopMessageStageMode)
        && normalizeText(existing.stopMessageAiMode) === normalizeText(persisted.stopMessageAiMode);
}
function overlayPersistedUsage(existing, persisted) {
    return {
        ...existing,
        stopMessageUsed: persisted.stopMessageUsed,
        stopMessageLastUsedAt: persisted.stopMessageLastUsedAt,
        stopMessageAiSeedPrompt: persisted.stopMessageAiSeedPrompt,
        stopMessageAiHistory: persisted.stopMessageAiHistory
    };
}
/**
 * Decide whether we should overwrite in-memory stopMessage fields with persisted ones.
 *
 * Key invariant:
 * - In-memory state may be ahead of disk because persistence is async (tmp+rename).
 * - Persisted state must still be able to update usage counters (stop_message_auto).
 *
 * Strategy:
 * - If existing has a newer stopMessageUpdatedAt than persisted → keep existing config by default.
 * - However, when persisted carries the same stopMessage config but newer usage progress,
 *   prefer the persisted counters so Virtual Router logs/state reflect real stop_message_auto consumption.
 * - Otherwise → adopt persisted fully.
 */
export function mergeStopMessageFromPersisted(existing, persisted) {
    if (!persisted) {
        return { ...existing };
    }
    const existingUpdatedAt = updatedAtOf(existing);
    const persistedUpdatedAt = updatedAtOf(persisted);
    const existingIsNewer = existingUpdatedAt !== null && (persistedUpdatedAt === null || persistedUpdatedAt < existingUpdatedAt);
    if (existingIsNewer) {
        const existingUsed = usedOf(existing) ?? 0;
        const persistedUsed = usedOf(persisted) ?? 0;
        const existingLastUsedAt = lastUsedAtOf(existing);
        const persistedLastUsedAt = lastUsedAtOf(persisted);
        const persistedHasUsageProgress = persistedUsed > existingUsed
            && (existingLastUsedAt === null || (persistedLastUsedAt !== null && persistedLastUsedAt >= existingLastUsedAt));
        if (persistedHasUsageProgress && sameStopMessageConfig(existing, persisted)) {
            return overlayPersistedUsage(existing, persisted);
        }
        return { ...existing };
    }
    return {
        ...existing,
        stopMessageSource: persisted.stopMessageSource,
        stopMessageText: persisted.stopMessageText,
        stopMessageMaxRepeats: persisted.stopMessageMaxRepeats,
        stopMessageUsed: persisted.stopMessageUsed,
        stopMessageStageMode: persisted.stopMessageStageMode,
        stopMessageAiMode: persisted.stopMessageAiMode,
        stopMessageAiSeedPrompt: persisted.stopMessageAiSeedPrompt,
        stopMessageAiHistory: persisted.stopMessageAiHistory,
        stopMessageUpdatedAt: persisted.stopMessageUpdatedAt,
        stopMessageLastUsedAt: persisted.stopMessageLastUsedAt
    };
}
