const locallyEditedSuggestedEdits = new Map();
// Suggestions removed locally (reverted to a no-op or deleted) while related
// async work — debounced saves, save-acks, socket echoes, refetches — may still
// be in flight. Every state ingestion path consults this set so a removed
// suggestion can never be resurrected by a late response. Ids are uuids and
// never reused, so entries are retained for the session; releasing them early
// would re-open the race for any save scheduled after the removal.
const removedSuggestedEditIds = new Set();
export function markSuggestedEditRemoved(id) {
    removedSuggestedEditIds.add(id);
    locallyEditedSuggestedEdits.delete(id);
}
export function isSuggestedEditRemoved(id) {
    return removedSuggestedEditIds.has(id);
}
function toTime(value) {
    if (!value)
        return 0;
    const timestamp = new Date(value).getTime();
    return Number.isFinite(timestamp) ? timestamp : 0;
}
function isIncomingOlder(current, incoming) {
    const currentTime = toTime(current.updated);
    const incomingTime = toTime(incoming.updated);
    return currentTime > 0 && incomingTime > 0 && currentTime > incomingTime;
}
function rememberLocalSuggestedEdit(edit) {
    locallyEditedSuggestedEdits.set(edit.id, {
        author: edit.author,
        fieldId: edit.fieldId,
        itemId: edit.itemId,
        mainItemLanguage: edit.mainItemLanguage,
        mainItemVersion: edit.mainItemVersion,
        newValue: edit.newValue,
    });
}
function forgetLocalSuggestedEdit(edit) {
    if (edit.status !== "pending") {
        locallyEditedSuggestedEdits.delete(edit.id);
    }
}
function hasNewerLocalSuggestionValue(current, incoming, options) {
    if (options.source !== "socket")
        return false;
    const local = locallyEditedSuggestedEdits.get(incoming.id);
    if (!local)
        return false;
    if (local.newValue === incoming.newValue)
        return false;
    return (current.newValue === local.newValue &&
        incoming.status === "pending" &&
        incoming.author === local.author &&
        incoming.fieldId === local.fieldId &&
        incoming.itemId === local.itemId &&
        incoming.mainItemLanguage === local.mainItemLanguage &&
        incoming.mainItemVersion === local.mainItemVersion);
}
function shouldAcceptSuggestedEditUpdate(current, incoming, options) {
    if (!current)
        return true;
    if (hasNewerLocalSuggestionValue(current, incoming, options)) {
        return false;
    }
    if (options.expectedNewValue !== undefined &&
        current.newValue !== options.expectedNewValue) {
        return false;
    }
    return !isIncomingOlder(current, incoming);
}
export function upsertSuggestedEdit(suggestedEdits, incoming, options = {}) {
    if (isSuggestedEditRemoved(incoming.id)) {
        return suggestedEdits;
    }
    const index = suggestedEdits.findIndex((edit) => edit.id === incoming.id);
    if (index !== -1) {
        const acceptUpdate = shouldAcceptSuggestedEditUpdate(suggestedEdits[index], incoming, options);
        if (!acceptUpdate) {
            return suggestedEdits;
        }
        const updated = [...suggestedEdits];
        updated[index] = incoming;
        if (options.source === "local") {
            rememberLocalSuggestedEdit(incoming);
        }
        else {
            forgetLocalSuggestedEdit(incoming);
        }
        return updated;
    }
    if (options.source === "local") {
        rememberLocalSuggestedEdit(incoming);
    }
    return [...suggestedEdits, incoming];
}
export function replacePendingSuggestionForSameField(suggestedEdits, incoming) {
    if (isSuggestedEditRemoved(incoming.id)) {
        return suggestedEdits;
    }
    return [
        ...suggestedEdits.filter((edit) => !(edit.status === "pending" &&
            edit.mainItemId === incoming.mainItemId &&
            edit.mainItemLanguage === incoming.mainItemLanguage &&
            edit.mainItemVersion === incoming.mainItemVersion &&
            edit.itemId === incoming.itemId &&
            edit.fieldId === incoming.fieldId &&
            edit.author === incoming.author)),
        incoming,
    ];
}
//# sourceMappingURL=suggestedEditState.js.map