health_trend_control.dart 2.67 KB
import 'package:get/get.dart';

import '../../report_common/config/report_date_range_config.dart';
import '../../report_common/models/report_period.dart';

mixin HealthTrendControl on GetxController {
  static const int typeCount = 3;

  final selectedTypeIndex = 0.obs;
  final selectedPeriod = ReportPeriod.week.obs;
  final selectedDate = ReportDateRangeConfig.clampDate(DateTime.now()).obs;
  final List<ReportPeriod> _periodsByType = List.of(const [
    ReportPeriod.week,
    ReportPeriod.day,
    ReportPeriod.day,
  ]);
  final List<DateTime> _datesByType = List.generate(
    typeCount,
    (_) => ReportDateRangeConfig.clampDate(DateTime.now()),
  );

  void changeType(int index) {
    final nextIndex = normalizeTypeIndex(index);
    selectedTypeIndex.value = nextIndex;
    _periodsByType[nextIndex] =
        normalizePeriod(nextIndex, _periodsByType[nextIndex]);
    selectedPeriod.value = _periodsByType[nextIndex];
    selectedDate.value = _datesByType[nextIndex];
  }

  void changePeriod(ReportPeriod period) {
    final typeIndex = normalizeTypeIndex(selectedTypeIndex.value);
    final nextPeriod = normalizePeriod(typeIndex, period);
    _periodsByType[typeIndex] = nextPeriod;
    selectedPeriod.value = nextPeriod;
  }

  void changeQuery(ReportPeriod period, DateTime date) {
    final typeIndex = normalizeTypeIndex(selectedTypeIndex.value);
    final nextPeriod = normalizePeriod(typeIndex, period);
    final nextDate = ReportDateRangeConfig.clampDate(date);
    _periodsByType[typeIndex] = nextPeriod;
    _datesByType[typeIndex] = nextDate;
    selectedPeriod.value = nextPeriod;
    selectedDate.value = nextDate;
  }

  void changeDate(DateTime date) {
    final typeIndex = normalizeTypeIndex(selectedTypeIndex.value);
    final nextDate = ReportDateRangeConfig.clampDate(date);
    _datesByType[typeIndex] = nextDate;
    selectedDate.value = nextDate;
  }

  ReportPeriod periodForType(int typeIndex) {
    final normalizedIndex = normalizeTypeIndex(typeIndex);
    return normalizePeriod(normalizedIndex, _periodsByType[normalizedIndex]);
  }

  DateTime dateForType(int typeIndex) {
    return _datesByType[normalizeTypeIndex(typeIndex)];
  }

  int normalizeTypeIndex(int index) =>
      index >= 0 && index < typeCount ? index : 0;

  ReportPeriod normalizePeriod(int typeIndex, ReportPeriod period) {
    final periods = supportedPeriods(normalizeTypeIndex(typeIndex));
    return periods.contains(period) ? period : periods.first;
  }

  List<ReportPeriod> supportedPeriods(int typeIndex) {
    return normalizeTypeIndex(typeIndex) == 0
        ? const [ReportPeriod.week, ReportPeriod.month, ReportPeriod.year]
        : const [ReportPeriod.day, ReportPeriod.week, ReportPeriod.month];
  }
}