• Calculate what changes will occur when syncing a manga entry. Determines which fields (status, progress, score, privacy) will change based on config priorities.

    Parameters

    • kenmei: KenmeiMangaData

      Kenmei manga data.

    • userEntry: undefined | UserEntryData

      Existing AniList entry data (undefined if new).

    • syncConfig: SyncConfig

      Sync configuration with priority settings.

    Returns SyncChangesResult

    Object describing all changes and their count.

    export function calculateSyncChanges(
    kenmei: KenmeiMangaData,
    userEntry: UserEntryData | undefined,
    syncConfig: SyncConfig,
    ): SyncChangesResult {
    const shouldUpdateStatus = (): boolean => {
    if (!userEntry) return true;
    if (syncConfig.prioritizeAniListStatus) return false;
    const effective = getEffectiveStatus(kenmei, syncConfig);
    const preservesCompleted =
    userEntry.status === "COMPLETED" && syncConfig.preserveCompletedStatus;
    return effective !== userEntry.status && !preservesCompleted;
    };

    const shouldUpdateProgress = (): boolean => {
    if (!userEntry) return true;
    const kenmeiProgress = kenmei.chaptersRead || 0;
    const aniProgress = userEntry.progress || 0;
    if (syncConfig.prioritizeAniListProgress) {
    return kenmeiProgress > aniProgress; // only if Kenmei ahead
    }
    return kenmeiProgress !== aniProgress;
    };

    const shouldUpdateScore = (): boolean => {
    const kenmeiScore = Number(kenmei.score || 0);
    if (!userEntry) return kenmeiScore > 0;

    // If preserving completed entries, don't touch score
    if (
    userEntry.status === "COMPLETED" &&
    syncConfig.preserveCompletedStatus
    ) {
    return false;
    }

    // If AniList score is preferred and meaningful, don't change
    if (
    syncConfig.prioritizeAniListScore &&
    userEntry.score &&
    Number(userEntry.score) > 0
    ) {
    return false;
    }

    const aniScore = Number(userEntry.score || 0);
    return (
    kenmeiScore > 0 &&
    (aniScore === 0 || Math.abs(kenmeiScore - aniScore) >= 0.5)
    );
    };

    const statusWillChange = shouldUpdateStatus();
    const progressWillChange = shouldUpdateProgress();
    const scoreWillChange = shouldUpdateScore();

    const isNewEntry = !userEntry;
    const isCompleted = userEntry?.status === "COMPLETED";

    const shouldSetPrivate = userEntry
    ? syncConfig.setPrivate && !userEntry.private
    : syncConfig.setPrivate;
    const changeCount = [
    statusWillChange,
    progressWillChange,
    scoreWillChange,
    shouldSetPrivate,
    ].filter(Boolean).length;

    return {
    statusWillChange,
    progressWillChange,
    scoreWillChange,
    isNewEntry,
    isCompleted,
    changeCount,
    };
    }