Files
GSFV2/gsf/lib/views/pages/MenstrualCycleTracker/Helper/HelperMethods.dart
2024-06-25 12:55:48 +05:30

377 lines
13 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gsp_app/views/pages/MenstrualCycleTracker/viewModel/StoringDates.dart';
import 'package:intl/intl.dart';
import 'package:syncfusion_flutter_datepicker/datepicker.dart';
import '../../../../api/base_manager.dart';
import 'StorageService.dart';
class HelperMethods extends GetxController {
RxString fertility = "May not be fertile".obs;
Rx<Color> fertilityColor = Color(0xFFFFEB3B).obs;
RxString observableDateTime = "15 December".obs;
RxString observableDateTimeOnTrackerHomePage =
DateFormat('dd MMMM').format(DateTime.now()).obs;
Rx<DateTime?> updateDateForHomepage = DateTime.now().obs;
RxBool overviewButtonColorTransparent = false.obs;
changeObservableDateTimeOnTrackerHomePage(bool front) {
DateTime currentDate =
DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
// Set the current year to the parsed date
DateTime updatedDate = DateTime(
DateTime.now().year,
currentDate.month,
currentDate.day,
);
// Add one day to the current date
if (front) {
updatedDate = updatedDate.add(Duration(days: 1));
currentPositionInCycleIndex + 1;
} else {
updatedDate = updatedDate.subtract(Duration(days: 1));
currentPositionInCycleIndex - 1;
}
//For HomePage
updateDateForHomepage.value = updatedDate;
// Format the updated date and update the observable
observableDateTimeOnTrackerHomePage.value =
DateFormat('dd MMMM').format(updatedDate);
calculateOutOfDays();
}
updateFertility(String value) {
fertility.value = value;
}
// Method to format DateTime as "dd MMMM" (e.g., "15 December")
formatDateTime(DateTime dateTime) {
observableDateTime.value = DateFormat('dd MMMM').format(dateTime);
}
RxBool showPeriodCycleText = true.obs;
RxString formattedDay = "".obs;
// Method to format DateTime as "dd" for periodCycle 1/22 on overview page
formatDateTime2(DateTime dateTime) {
formattedDay.value = DateFormat('dd').format(dateTime);
if (int.parse(formattedDay.value) > currentPeriodCycle.value) {
showPeriodCycleText.value = false;
} else {
showPeriodCycleText.value = true;
}
}
//Period calculation
Rx<DateTime?> firstPeriodDate = Rx<DateTime?>(null);
RxInt periodCycleLength = RxInt(0);
RxInt periodLength = RxInt(0);
RxList<DateTime?> predictedDate = <DateTime?>[].obs;
RxList<PickerDateRange> pickerdateRange = <PickerDateRange>[].obs;
//---------++++++++++--------------
//Other days calculation
RxList<DateTime?> fertileDates = <DateTime?>[].obs;
RxList<DateTime?> ovulatingDate = <DateTime?>[].obs;
//RxList<DateTime?> notfertilityDates = <DateTime?>[].obs;
List<int> periodCycleLengthList = [];
RxBool isLoading = true.obs;
// -----------+++++++++++++-----------
calculateFirstTime() async {
predictedDate.add(
firstPeriodDate.value!.add(Duration(days: periodCycleLength.value)));
pickerdateRange.add(PickerDateRange(firstPeriodDate.value,
firstPeriodDate.value!.add(Duration(days: periodLength.value - 1))));
periodCycleLengthList.add(periodCycleLength.value);
if (periodCycleLength.value > 21) {
ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14)));
}
List<Map<String, DateTime>> dateMaps = [];
// Iterate through selectedRanges and add each PickerDateRange to the list of maps
for (PickerDateRange range in pickerdateRange.value) {
Map<String, DateTime> dateMap = {
"start": range.startDate ?? DateTime.now(),
"end": range.endDate ?? DateTime.now(),
};
dateMaps.add(dateMap);
}
var updata = {
"predicted_dates": predictedDate.value.toString(),
"fertile_dates": fertileDates.value.toString(),
"ovulating_dates": ovulatingDate.value.toString(),
"pickerdateRange": dateMaps.toString(),
"period_cycle_length": periodCycleLengthList.first
};
final resp = await StoringDates().storeAllList(updata);
if (resp.status == ResponseStatus.SUCCESS) {
Future.delayed(const Duration(seconds: 2), () {
isLoading.value = false;
});
StorageService().storeinitialSetup();
}
}
// reCalculateFromApi() {
// predictedDate.add(
// firstPeriodDate.value!.add(Duration(days: periodCycleLength.value)));
// pickerdateRange.add(PickerDateRange(firstPeriodDate.value,
// firstPeriodDate.value!.add(Duration(days: periodLength.value - 1))));
// periodCycleLengthList.add(periodCycleLength.value);
// if (periodCycleLength.value > 21) {
// ovulatingDate.add(firstPeriodDate.value!.add(const Duration(days: 14)));
// }
// }
recalculate() async {
List<int> data = calculatePeriodCycleLength();
predictedDate.clear();
ovulatingDate.clear();
for (var i = 0; i < pickerdateRange.length; i++) {
predictedDate
.add(pickerdateRange[i].startDate!.add(Duration(days: data[i])));
if (periodCycleLength.value > 21) {
ovulatingDate
.add(pickerdateRange[i].startDate!.add(const Duration(days: 14)));
}
}
List<Map<String, DateTime>> dateMaps = [];
// Iterate through selectedRanges and add each PickerDateRange to the list of maps
for (PickerDateRange range in pickerdateRange.value) {
Map<String, DateTime> dateMap = {
"start": range.startDate ?? DateTime.now(),
"end": range.endDate ?? DateTime.now(),
};
dateMaps.add(dateMap);
}
var updata = {
"predicted_dates": predictedDate.value.toString(),
"fertile_dates": fertileDates.value.toString(),
"ovulating_dates": ovulatingDate.value.toString(),
"pickerdateRange": dateMaps.toString(),
"period_cycle_length": periodCycleLengthList.first
};
//await StoringDates().storeAllList(updata);
isLoading.value = true;
final resp = await StoringDates().storeAllList(updata);
if (resp.status == ResponseStatus.SUCCESS) {
Future.delayed(const Duration(seconds: 1), () {
isLoading.value = false;
});
StorageService().storeinitialSetup();
}
getLast5PeriodDates();
}
List<int> calculatePeriodCycleLength() {
if (pickerdateRange.length >= 2) {
// int totalPeriodCycleLength = 0;
// // Clear all elements except the first one
if (periodCycleLengthList.length > 1) {
periodCycleLengthList.removeRange(1, periodCycleLengthList.length);
}
pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!));
// Calculate the sum of period cycle lengths
for (int i = 0; i < pickerdateRange.length - 1; i++) {
DateTime? currentStartDate = pickerdateRange[i].startDate;
DateTime? nextStartDate = pickerdateRange[i + 1].startDate;
// Calculate the difference in days and add it to the list
int periodCycleLength =
nextStartDate!.difference(currentStartDate!).inDays;
periodCycleLengthList.add(periodCycleLength);
}
// // Calculate the average period cycle length
// int averagePeriodCycleLength =
// totalPeriodCycleLength ~/ (pickerdateRange.length - 1);
}
return periodCycleLengthList;
// avg end ++++++++--------+++++
// if (pickerdateRange.length >= 2) {
// pickerdateRange.sort((a, b) => a.startDate!.compareTo(b.startDate!));
// DateTime? secondLastStartDate =
// pickerdateRange[pickerdateRange.length - 2].startDate;
// DateTime? lastStartDate = pickerdateRange.last.startDate;
// // Calculate the period cycle length in days
// int periodCycleLength =
// lastStartDate!.difference(secondLastStartDate!).inDays;
// print("calculated period cycle length is $periodCycleLength");
// // Clear all elements except the first one
// if (periodCycleLengthList.length > 1) {
// periodCycleLengthList.removeRange(1, periodCycleLengthList.length);
// }
// periodCycleLengthList.add(periodCycleLength);
// }
// return periodCycleLengthList;
}
Rx<DateTime?> predictedPeriodCycleForHomePage = Rx<DateTime?>(null);
// RxInt indexOfCurrentPeriodCycle = 0.obs;
int calculatePeriodCycle() {
DateTime currentDate = DateTime.now();
List<int> data = calculatePeriodCycleLength();
int index = predictedDate
.indexWhere((date) => date != null && date.isAfter(currentDate));
if (index >= 0) {
predictedPeriodCycleForHomePage.value = predictedDate[index];
//indexOfCurrentPeriodCycle.value = index;
return data[index];
} else {
return 99999;
}
}
RxInt currentPeriodCycle = 0.obs;
RxInt outOfDays = 0.obs;
calculateOutOfDays() {
int result = calculatePeriodCycle();
if (result != 99999) {
currentPeriodCycle.value = result;
triggerManipulation();
disabledNext = false.obs;
// showNext = true.obs;
// showPrev = true.obs;
} else {
showNext = false.obs;
showPrev = false.obs;
disabledNext = true.obs;
}
update();
}
RxBool showNext = true.obs;
RxBool showPrev = true.obs;
RxBool endOfCycle = true.obs;
RxBool disabledNext = false.obs;
triggerManipulation() {
if (currentPositionInCycleIndex.value == currentPeriodCycle.value) {
showNext.value = false;
endOfCycle.value = false;
} else if (currentPositionInCycleIndex.value == 0) {
showPrev.value = false;
} else {
showNext.value = true;
showPrev.value = true;
endOfCycle.value = true;
}
}
//for changing color of centre calendar icon
RxList<DateTime?> allDatesList = <DateTime?>[].obs;
calculatePeriodDateForCalender() {
allDatesList = generateAllDates(pickerdateRange);
}
RxList<DateTime?> generateAllDates(RxList<PickerDateRange> ranges) {
RxList<DateTime?> allDates = <DateTime?>[].obs;
for (var range in ranges) {
DateTime currentDate = range.startDate!;
while (currentDate.isBefore(range.endDate!) ||
currentDate.isAtSameMomentAs(range.endDate!)) {
allDates.add(currentDate);
currentDate = currentDate.add(const Duration(days: 1));
}
}
return allDates;
}
storePredictedDateFromApi(List<String> dateStrings) {
List<DateTime?> predictedDates =
dateStrings.map((dateString) => DateTime.parse(dateString)).toList();
predictedDate.assignAll(predictedDates);
print("Predicted Dates: ${helperController.predictedDate.value}");
}
storeOvulatingDateFromApi(List<String> dateStrings) {
// Convert the List of strings into a List<DateTime>
List<DateTime> ovulatingDate1 =
dateStrings.map((dateString) => DateTime.parse(dateString)).toList();
ovulatingDate.value = ovulatingDate1;
}
storeFirstPeriodDate() {
helperController.firstPeriodDate.value = pickerdateRange.first.startDate;
}
storePeriodCycles(response) {
periodCycleLengthList.add(response);
periodCycleLength.value = response;
}
List<DateTime> last5startDates = [];
getLast5PeriodDates() {
// Calculate the number of elements to consider (minimum between 5 and the list length)
int elementsToConsider =
pickerdateRange.length < 5 ? pickerdateRange.length : 5;
last5startDates.clear();
// Extract start dates from the last elementsToConsider ranges
for (int i = pickerdateRange.length - elementsToConsider;
i < pickerdateRange.length;
i++) {
last5startDates.add(pickerdateRange[i].startDate!);
}
// Now, startDates contains the last elementsToConsider start dates
print("Start Dates: $last5startDates");
}
RxInt currentPositionInCycleIndex = 0.obs;
calculateCurrentPositionInCycle(DateTime valueFromOverview) {
List<DateTime> dateList = generateDateList(
pickerdateRange.last.startDate!,
helperController.predictedPeriodCycleForHomePage.value ??
DateTime.now());
// Search date which was visible on Homepage Inside circle
// DateTime currentDate1 =
// DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
// //Search date which is in overview page -> Period cycle:
// DateTime currentDate1 =
// DateFormat('dd MMMM').parse(observableDateTimeOnTrackerHomePage.value);
// // Set the current year to the parsed date
// DateTime updatedDate = DateTime(
// DateTime.now().year,
// currentDate1.month,
// currentDate1.day,
// );
currentPositionInCycleIndex.value = dateList.indexOf(valueFromOverview);
if (currentPositionInCycleIndex.value == -1) {
showPeriodCycleText.value = false;
}
}
List<DateTime> generateDateList(DateTime startDate, DateTime endDate) {
List<DateTime> dateList = [];
dateList.add(startDate);
while (startDate.isBefore(endDate)) {
startDate = startDate.add(Duration(days: 1));
dateList.add(startDate);
}
return dateList;
}
}