import type { Activity } from '@/types'; // This file is deprecated - functionality moved to metricAcwr.ts // Kept for reference only interface ACWRData { dates: string[]; acwr: (number | null)[]; acuteLoad: (number | null)[]; chronicLoad: (number | null)[]; } /** * Calculate Acute-Chronic Workload Ratio (ACWR) * Acute load: 7-day rolling average * Chronic load: 28-day rolling average * ACWR = Acute / Chronic * Optimal range: 0.8 - 1.3 */ export function calculateACWR(activities: Activity[], dateRange?: { start: Date; end: Date }): ACWRData { if (activities.length === 0 && !dateRange) { return { dates: [], acwr: [], acuteLoad: [], chronicLoad: [] }; } const dates: string[] = []; const acwr: (number | null)[] = []; const acuteLoad: (number | null)[] = []; const chronicLoad: (number | null)[] = []; // Create a map of date to total load (using TSS, or distance as fallback) const dailyLoad = new Map(); activities.forEach(activity => { const dateKey = activity.date.toISOString().split('T')[0]; const load = activity.trainingStressScore || activity.distance || 0; if (!dailyLoad.has(dateKey)) { dailyLoad.set(dateKey, 0); } dailyLoad.set(dateKey, dailyLoad.get(dateKey)! + load); }); // Get all dates in range const startDate = dateRange?.start || (activities.length > 0 ? activities[0].date : new Date()); const endDate = dateRange?.end || (activities.length > 0 ? activities[activities.length - 1].date : new Date()); const allDates: Date[] = []; for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) { allDates.push(new Date(d)); } // Calculate ACWR for each date allDates.forEach((date, index) => { const dateKey = date.toISOString().split('T')[0]; dates.push(dateKey); // Need at least 28 days of data for chronic load if (index < 27) { acuteLoad.push(null); chronicLoad.push(null); acwr.push(null); return; } // Calculate acute load (7-day average) let acuteSum = 0; for (let i = 0; i < 7; i++) { const d = allDates[index - i]; const key = d.toISOString().split('T')[0]; acuteSum += dailyLoad.get(key) || 0; } const acuteAvg = acuteSum / 7; // Calculate chronic load (28-day average) let chronicSum = 0; for (let i = 0; i < 28; i++) { const d = allDates[index - i]; const key = d.toISOString().split('T')[0]; chronicSum += dailyLoad.get(key) || 0; } const chronicAvg = chronicSum / 28; acuteLoad.push(acuteAvg); chronicLoad.push(chronicAvg); // Calculate ACWR if (chronicAvg > 0) { acwr.push(acuteAvg / chronicAvg); } else { acwr.push(null); } }); return { dates, acwr, acuteLoad, chronicLoad }; }