import 'dart:math'; import 'package:ernaehrung/android/components/meal_page_text/days_component.dart'; import 'package:ernaehrung/android/config/cast_helper.dart'; import 'package:hive/hive.dart'; import '../models/food.dart'; class StatisticsService { final String reducedStatisticsBoxName = 'STATISTICS_REDUCED'; final String mainStatisticsBoxName = 'STATISTICS_MAIN'; StatisticsService() { initBoxes(); } initBoxes()async{ Box reducedBox = Hive.box(reducedStatisticsBoxName); putIfKeyNotExists(reducedBox, 'FRÜHSTÜCK', []); putIfKeyNotExists(reducedBox, 'MITTAGESSEN', []); putIfKeyNotExists(reducedBox, 'ABENDESSEN', []); updateReducedBoxByTimespan(TimeSpan.day); } void putIfKeyNotExists(Box box, String key, dynamic value) { if (!box.containsKey(key)) { box.put(key, value); } } updateReducedBoxByTimespan(TimeSpan timeSpan){ clearReducedBoxBeforeUpdate(); DateTime now = DateTime.now(); int timestamp = now.millisecondsSinceEpoch.toInt() ~/ 1000; switch(timeSpan){ case TimeSpan.day: getNewFoodAndUpdateReducedBoxByTimestamp(timestamp); break; case TimeSpan.week: List currentWeek = getTimestampsByTimestampAndTimespan(TimeSpan.week,timestamp); for(int i = 0;i < currentWeek.length;i++){ getNewFoodAndUpdateReducedBoxByTimestamp(currentWeek[i]); } break; case TimeSpan.month: List currentMonth = getTimestampsByTimestampAndTimespan(TimeSpan.month,timestamp); for(int i = 0;i < currentMonth.length;i++){ getNewFoodAndUpdateReducedBoxByTimestamp(currentMonth[i]); } break; } } void getNewFoodAndUpdateReducedBoxByTimestamp(int timestamp){ Map> newFood = getFoodMapForGivenTimestampFromMainBox(timestamp); if(newFood.keys.isNotEmpty){ setElementsOfReducedBox(newFood); } } List getTimestampsByTimestampAndTimespan(TimeSpan timespan, int timestamp) { int range = timespan == TimeSpan.week ? 7 : 31; int targetWeekday = DateTime.monday; // Example target weekday (Monday) DateTime currentDateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); int currentWeekday = currentDateTime.weekday; int daysToAdd = targetWeekday - currentWeekday; DateTime targetDateTime = currentDateTime.add(Duration(days: daysToAdd)); List timestampsForWeekdays = []; for (int i = 0; i < range; i++) { timestampsForWeekdays.add(targetDateTime.millisecondsSinceEpoch ~/ 1000); targetDateTime = targetDateTime.add(const Duration(days: 1)); } return timestampsForWeekdays; } clearReducedBoxBeforeUpdate(){ Box box = Hive.box(reducedStatisticsBoxName); for(int i = 0; i < box.keys.length;i++){ box.put(box.keys.elementAt(i), []); } } setElementsOfReducedBox(Map> newFood){ Box box = Hive.box(reducedStatisticsBoxName); Iterable keys = newFood.keys; for(int i = 0; i < keys.length;i++){ addValuesToList(box, keys.elementAt(i), newFood[keys.elementAt(i)] ?? []); } } void addValuesToList(Box box, String key, List newValues){ List existingList = castDynamicToListFood(box.get(key)); for(int i = 0; i < newValues.length;i++){ existingList.add(newValues[i]); } box.put(key, existingList); } getDayAsIntFromTimestamp(int timestamp){ DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); return dateTime.day; } Map> getFoodMapForGivenTimestampFromMainBox(int timestamp){ Box box = Hive.box(mainStatisticsBoxName); dynamic matchingTimestamp = getMatchingTimeStamp(box, timestamp); if(matchingTimestamp != null){ return castDynamicMap(box.get(matchingTimestamp)); } return >{}; } getMatchingTimeStamp(Box box,int newTimestamp){ if(box.keys.isNotEmpty){ for(int i = 0; i < box.keys.length;i++){ int timestamp = box.keys.elementAt(i); if(isDateEqual(newTimestamp, timestamp)){ return timestamp; } } return null; } } getMonthAsIntFromTimestamp(int timestamp){ DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); return dateTime.month; } getYearAsIntFromTimestamp(int timestamp){ DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); return dateTime.year; } isDateEqual(int timestamp1, int timestamp2){ return getDayAsIntFromTimestamp(timestamp1) == getDayAsIntFromTimestamp(timestamp2) && getMonthAsIntFromTimestamp(timestamp1) == getMonthAsIntFromTimestamp(timestamp2) && getYearAsIntFromTimestamp(timestamp1) == getYearAsIntFromTimestamp(timestamp2); } addItemToMainBox(Food value, String mealType){ // Hive.deleteFromDisk(); Box box = Hive.box(mainStatisticsBoxName); DateTime dateTime = DateTime.now(); // DEBUG //DateTime dateTime = getRandomTimestampForTesting(); int newTimestamp = dateTime.millisecondsSinceEpoch.toInt() ~/ 1000; dynamic matchingTimestamp = getMatchingTimeStamp(box, newTimestamp); if(matchingTimestamp != null){ newTimestamp = matchingTimestamp; } Map> valueMap = castDynamicMap(box.get(newTimestamp)); List values = []; if(valueMap.containsKey(mealType)){ values = valueMap[mealType]!; } values.add(value); valueMap[mealType] = values; box.put(newTimestamp, valueMap); } getRandomTimestampForTesting(){ DateTime now = DateTime.now(); DateTime startOfWeek = now.subtract(Duration(days: now.weekday - 1)); DateTime endOfWeek = startOfWeek.add(const Duration(days: 6)); Random random = Random(); int randomMilliseconds = random.nextInt(endOfWeek.millisecondsSinceEpoch - startOfWeek.millisecondsSinceEpoch); DateTime randomTimestamp = startOfWeek.add(Duration(milliseconds: randomMilliseconds)); return randomTimestamp; } num getAllCaloriesByBoxAndTimestamp(Box box,DateTime date){ int timestamp = date.millisecondsSinceEpoch.toInt() ~/ 1000; Map> valueMap = castDynamicMap(box.get(timestamp)); num sum = 0; for(var mealType in valueMap.keys){ if(valueMap.containsKey(mealType)){ List values = valueMap[mealType]!; for(var value in values){ sum += value.calories; } } } return sum; } num getCaloriesByTimestampAndMealTypeAndBox(Box box,DateTime date, String mealType){ int timestamp = date.millisecondsSinceEpoch.toInt() ~/ 1000; Map> valueMap = castDynamicMap(box.get(timestamp)); num sum = 0; if(valueMap.containsKey(mealType)){ List values = valueMap[mealType]!; for(var value in values){ sum += value.calories; } } return sum; } showItems(){ print("Statistics.dart - showItems() - ITEMS"); //Hive.box(boxName).clear(); print(Hive.box(mainStatisticsBoxName).keys.length); for(int i = 0; i < Hive.box(mainStatisticsBoxName).keys.length; i++){ print(Hive.box(mainStatisticsBoxName).keys.elementAt(i)); print(Hive.box(mainStatisticsBoxName).values.elementAt(i)); //print(Hive.box(boxName).keys.elementAt(i) + " " + Hive.box(boxName).values.elementAt(i)); } } }