import { BehaviorDataPoint, CycleData } from '../types.ts'; type TimeRange = '24h' | '7d' | '30d' | 'cycle'; export const generateBehaviorChartData = ( data: BehaviorDataPoint[], timeRange: TimeRange, cycleData: CycleData ) => { const now = new Date(); if (timeRange === '24h') { const hourlyAverages: { [key: string]: { totalActivity: number; totalStress: number; count: number }; } = {}; const startOfPeriod = new Date(now); startOfPeriod.setHours(startOfPeriod.getHours() - 24); data.forEach((point) => { if (point.timestamp >= startOfPeriod) { const hourKey = `${point.timestamp.getFullYear()}-${point.timestamp.getMonth()}-${point.timestamp.getDate()}-${point.timestamp.getHours()}`; if (!hourlyAverages[hourKey]) { hourlyAverages[hourKey] = { totalActivity: 0, totalStress: 0, count: 0 }; } hourlyAverages[hourKey].totalActivity += point.activity; hourlyAverages[hourKey].totalStress += point.stress; hourlyAverages[hourKey].count++; } }); const result: { date: string; activity: number; stress: number }[] = []; for (let i = 23; i >= 0; i--) { const date = new Date(now); date.setHours(now.getHours() - i, 0, 0, 0); const hourKey = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}-${date.getHours()}`; const hourString = date.toLocaleTimeString('id-ID', { hour: '2-digit' }) + ':00'; if (hourlyAverages[hourKey]) { result.push({ date: hourString, activity: hourlyAverages[hourKey].totalActivity / hourlyAverages[hourKey].count, stress: hourlyAverages[hourKey].totalStress / hourlyAverages[hourKey].count, }); } else { result.push({ date: hourString, activity: 0, stress: 0 }); } } return result; } if (timeRange === 'cycle') { const weeklyAverages: { [key: string]: { totalActivity: number; totalStress: number; count: number }; } = {}; const cycleStartDate = new Date(cycleData.startDate); const totalWeeks = Math.ceil(cycleData.totalDays / 7); for (let i = 1; i <= totalWeeks; i++) { weeklyAverages[`M${i}`] = { totalActivity: 0, totalStress: 0, count: 0 }; } data.forEach((point) => { if (point.timestamp >= cycleStartDate) { const diffTime = point.timestamp.getTime() - cycleStartDate.getTime(); const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24)); if (diffDays >= 0 && diffDays < cycleData.totalDays) { const weekNumber = Math.floor(diffDays / 7) + 1; if (weekNumber > 0 && weekNumber <= totalWeeks) { weeklyAverages[`M${weekNumber}`].totalActivity += point.activity; weeklyAverages[`M${weekNumber}`].totalStress += point.stress; weeklyAverages[`M${weekNumber}`].count++; } } } }); return Object.entries(weeklyAverages).map(([date, values]) => ({ date, activity: values.count > 0 ? values.totalActivity / values.count : 0, stress: values.count > 0 ? values.totalStress / values.count : 0, })); } const days = timeRange === '7d' ? 7 : 30; const dailyAverages: { [key: string]: { totalActivity: number; totalStress: number; count: number }; } = {}; for (let i = days - 1; i >= 0; i--) { const date = new Date(now); date.setDate(now.getDate() - i); const formatOptions: Intl.DateTimeFormatOptions = timeRange === '7d' ? { weekday: 'short' } : { day: 'numeric', month: 'short' }; const dateString = date.toLocaleDateString('id-ID', formatOptions); dailyAverages[dateString] = { totalActivity: 0, totalStress: 0, count: 0 }; } const startOfPeriod = new Date(now); startOfPeriod.setDate(startOfPeriod.getDate() - days); startOfPeriod.setHours(0, 0, 0, 0); data.forEach((point) => { if (point.timestamp >= startOfPeriod) { const formatOptions: Intl.DateTimeFormatOptions = timeRange === '7d' ? { weekday: 'short' } : { day: 'numeric', month: 'short' }; const dateString = point.timestamp.toLocaleDateString('id-ID', formatOptions); if (dailyAverages[dateString]) { dailyAverages[dateString].totalActivity += point.activity; dailyAverages[dateString].totalStress += point.stress; dailyAverages[dateString].count++; } } }); return Object.entries(dailyAverages).map(([date, values]) => ({ date, activity: values.count > 0 ? values.totalActivity / values.count : 0, stress: values.count > 0 ? values.totalStress / values.count : 0, })); };