• Merges new match results with existing ones to preserve user progress.

    Parameters

    Returns MatchResult[]

    Merged results with preserved user progress.

    const merged = mergeMatchResults(newResults);
    
    export function mergeMatchResults(newResults: MatchResult[]): MatchResult[] {
    try {
    // Get existing results
    const existingResults = getSavedMatchResults();
    if (
    !existingResults ||
    !Array.isArray(existingResults) ||
    existingResults.length === 0
    ) {
    console.log("No existing match results to merge, using new results");
    return newResults;
    }

    console.log(
    `Merging ${newResults.length} new results with ${existingResults.length} existing results`,
    );

    // Create a map of existing results for quick lookup by both ID and title
    const existingById = new Map<string, MatchResult>();
    const existingByTitle = new Map<string, MatchResult>();

    existingResults.forEach((match) => {
    if (match.kenmeiManga?.id) {
    existingById.set(match.kenmeiManga.id.toString(), match);
    }
    if (match.kenmeiManga?.title) {
    existingByTitle.set(match.kenmeiManga.title.toLowerCase(), match);
    }
    });

    // Process new results, preserving user progress from existing matches
    const processedResults = newResults.map((newMatch) => {
    // Try to find existing match by ID first
    let existingMatch = newMatch.kenmeiManga?.id
    ? existingById.get(newMatch.kenmeiManga.id.toString())
    : undefined;

    // If not found by ID, try title (case insensitive)
    if (!existingMatch && newMatch.kenmeiManga?.title) {
    existingMatch = existingByTitle.get(
    newMatch.kenmeiManga.title.toLowerCase(),
    );
    }

    // If we found a match AND it has user progress (not pending), preserve it
    if (existingMatch && existingMatch.status !== "pending") {
    console.log(
    `Preserving existing ${existingMatch.status} match for "${newMatch.kenmeiManga?.title}"`,
    );

    // Take new anilist matches but keep user's selected match and status
    return {
    ...newMatch,
    status: existingMatch.status,
    selectedMatch: existingMatch.selectedMatch,
    matchDate: existingMatch.matchDate,
    };
    }

    // Otherwise use the new match
    return newMatch;
    });

    // Create sets to track what we've processed
    const processedIds = new Set<string>();
    const processedTitles = new Set<string>();

    // Add all processed results to the tracking sets
    processedResults.forEach((result) => {
    if (result.kenmeiManga?.id) {
    processedIds.add(result.kenmeiManga.id.toString());
    }
    if (result.kenmeiManga?.title) {
    processedTitles.add(result.kenmeiManga.title.toLowerCase());
    }
    });

    // Find existing results that weren't in the new results and add them
    const unprocessedExistingResults = existingResults.filter(
    (existingMatch) => {
    // Skip if we already processed this manga by ID
    if (
    existingMatch.kenmeiManga?.id &&
    processedIds.has(existingMatch.kenmeiManga.id.toString())
    ) {
    return false;
    }

    // Skip if we already processed this manga by title
    if (
    existingMatch.kenmeiManga?.title &&
    processedTitles.has(existingMatch.kenmeiManga.title.toLowerCase())
    ) {
    return false;
    }

    // This is an existing result that wasn't in the new batch, so include it
    return true;
    },
    );

    if (unprocessedExistingResults.length > 0) {
    console.log(
    `Adding ${unprocessedExistingResults.length} existing results that weren't in the new batch`,
    );
    }

    // Combine processed results with unprocessed existing results
    const mergedResults = [...processedResults, ...unprocessedExistingResults];

    console.log(`Merged results: ${mergedResults.length} total items`);

    // Check how many preserved matches we have
    const preservedCount = mergedResults.filter(
    (m) => m.status !== "pending",
    ).length;
    console.log(
    `Preserved ${preservedCount} user reviews from previous imports`,
    );

    return mergedResults;
    } catch (error) {
    console.error("Error merging match results", error);
    return newResults; // Fall back to new results on error
    }
    }