• Computes reading velocity metrics (average chapters per day/week/month) with per-manga baseline.

    Parameters

    Returns {
        perDay: number;
        perWeek: number;
        perMonth: number;
        totalChapters: number;
        activeDays: number;
    }

    Velocity metrics object (perDay, perWeek, perMonth, totalChapters, activeDays).

    export function computeReadingVelocity(
    history: ReadingHistory,
    timeRange: TimeRange,
    ): {
    perDay: number;
    perWeek: number;
    perMonth: number;
    totalChapters: number;
    activeDays: number;
    } {
    const filtered = filterHistoryByTimeRange(history, timeRange);
    if (!filtered.length) {
    return {
    perDay: 0,
    perWeek: 0,
    perMonth: 0,
    totalChapters: 0,
    activeDays: 0,
    };
    }

    // Establish baseline from pre-range history
    const now = Date.now();
    const ranges = {
    "7d": 7 * 24 * 60 * 60 * 1000,
    "30d": 30 * 24 * 60 * 60 * 1000,
    "90d": 90 * 24 * 60 * 60 * 1000,
    };
    const cutoff = timeRange === "all" ? 0 : now - ranges[timeRange];
    const preRangeBaseline =
    timeRange === "all" ? new Map() : getPreRangeBaseline(history, cutoff);

    // Calculate total chapters read (sum of deltas)
    const sorted = [...filtered].sort((a, b) => a.timestamp - b.timestamp);
    const previousChapters = new Map<string | number, number>(preRangeBaseline);
    let totalChapters = 0;
    const activeDates = new Set<string>();

    for (const entry of sorted) {
    const prev = previousChapters.get(entry.mangaId) ?? 0;
    const delta = Math.max(0, entry.chaptersRead - prev);
    if (delta > 0) {
    totalChapters += delta;
    const date = getDateKey(entry.timestamp);
    activeDates.add(date);
    }
    previousChapters.set(entry.mangaId, entry.chaptersRead);
    }

    const activeDays = activeDates.size;

    const perDay = activeDays > 0 ? totalChapters / activeDays : 0;
    const perWeek = perDay * 7;
    const perMonth = perDay * 30;

    return {
    perDay: Math.round(perDay * 10) / 10,
    perWeek: Math.round(perWeek * 10) / 10,
    perMonth: Math.round(perMonth * 10) / 10,
    totalChapters,
    activeDays,
    };
    }