health_local_datasource.dart 6 KB
import 'package:doublefeel_flutter/core/error/app_error.dart';
import 'package:doublefeel_flutter/core/result/app_result.dart';
import 'package:doublefeel_flutter/core/services/health_raw_data_core_service.dart';
import 'package:doublefeel_flutter/data/models/enums/app_enums.dart';
import 'package:doublefeel_flutter/data/models/health/activity/activity_burn_statistics_data_v2.dart';
import 'package:doublefeel_flutter/data/models/health/health_v2_models.dart';
import 'package:doublefeel_flutter/data/models/health/hrv/hrv_statistics_data.dart';
import 'package:doublefeel_flutter/data/models/health/sleep/sleep_statistics_data.dart';

import 'health_datasource.dart';
import 'health_local_data_convert.dart';

class LocalHealthDataSource implements HealthDataSource {
  const LocalHealthDataSource({required this.coreService});

  final HealthRawDataCoreService coreService;

  @override
  Future<AppResult<SleepStatisticsData>> getSleepStatistics(
    int dateRangeType,
    int startDate, {
    int? queryUserId,
  }) async {
    try {
      final days = LocalHealthDataConvert.rangeDays(dateRangeType, startDate);
      if (days.isEmpty) return AppSuccess(SleepStatisticsData());

      final previousDays = LocalHealthDataConvert.previousRangeDays(
        dateRangeType,
        startDate,
      );
      final allDays = [...previousDays, ...days];
      final queryStart = LocalHealthDataConvert.unixSeconds(
        allDays.first.subtract(const Duration(hours: 12)),
      );
      final queryEnd = LocalHealthDataConvert.unixSeconds(
        allDays.last.add(const Duration(days: 1, hours: 12)),
      );
      final sleepIntervals = await coreService.queryRawSleepIntervals(
        startTime: queryStart,
        endTime: queryEnd,
      );
      final heartRate = await coreService.queryRawDataPoints(
        dataType: HealthDataUploadType.heartRate.type,
        startTime: queryStart,
        endTime: queryEnd,
      );

      return AppSuccess(
        LocalHealthDataConvert.sleepStatistics(
          days: days,
          previousDays: previousDays,
          sleepIntervals: sleepIntervals,
          heartRate: heartRate,
        ),
      );
    } catch (error) {
      return AppFailure(AppUnknownError(error));
    }
  }

  @override
  Future<AppResult<ActivityBurnStatisticsDataV2>> getActivityBurnStatistics(
    int dateRangeType,
    int startDate, {
    int? queryUserId,
  }) async {
    try {
      final days = LocalHealthDataConvert.rangeDays(dateRangeType, startDate);
      if (days.isEmpty) return AppSuccess(ActivityBurnStatisticsDataV2());

      final previousDays = LocalHealthDataConvert.previousRangeDays(
        dateRangeType,
        startDate,
      );
      final allDays = [...previousDays, ...days];
      final queryStart = LocalHealthDataConvert.unixSeconds(allDays.first);
      final queryEnd = LocalHealthDataConvert.unixSeconds(
        days.last.add(const Duration(days: 1)),
      );
      final activity = await coreService.queryRawActivitySummaries(
        startTime: queryStart,
        endTime: queryEnd,
      );
      final heartRate = await coreService.queryRawDataPoints(
        dataType: HealthDataUploadType.heartRate.type,
        startTime: queryStart,
        endTime: queryEnd,
      );
      final sleepIntervals = await coreService.queryRawSleepIntervals(
        startTime: queryStart,
        endTime: queryEnd,
      );

      return AppSuccess(
        LocalHealthDataConvert.activityBurnStatistics(
          days: days,
          previousDays: previousDays,
          activity: activity,
          heartRate: heartRate,
          sleepIntervals: sleepIntervals,
        ),
      );
    } catch (error) {
      return AppFailure(AppUnknownError(error));
    }
  }

  @override
  Future<AppResult<HrvStatisticsDataV2>> getHrvStatistics(
    int dateRangeType,
    int startDate, {
    int? queryUserId,
  }) async {
    try {
      final days = LocalHealthDataConvert.rangeDays(dateRangeType, startDate);
      if (days.isEmpty) return AppSuccess(HrvStatisticsDataV2());

      final queryStart = LocalHealthDataConvert.unixSeconds(days.first);
      final queryEnd = LocalHealthDataConvert.unixSeconds(
        days.last.add(const Duration(days: 1)),
      );
      final hrvPoints = await coreService.queryHrvStressPoints(
        startTime: queryStart,
        endTime: queryEnd,
      );
      final realtimePoints = await coreService.queryRealtimeStressPoints(
        startTime: queryStart,
        endTime: queryEnd,
      );

      return AppSuccess(
        LocalHealthDataConvert.hrvStatistics(
          dateRangeType: dateRangeType,
          days: days,
          hrvPoints: hrvPoints,
          realtimePoints: realtimePoints,
        ),
      );
    } catch (error) {
      return AppFailure(AppUnknownError(error));
    }
  }

  @override
  Future<AppResult<V2HealthEverUploaded>> getHealthDataEverUploaded() async {
    var data = V2HealthEverUploaded(flag: true);
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2ActivityTarget>> getV2ActivityTarget(
      int? queryUserId) async {
    var data = V2ActivityTarget(
      sleepTargetDuration: 480,
    );
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2HealthData>> getV2HealthData(
      int? queryUserId, int intDate) async {
    var data = V2HealthData(hrvAvg: 10);
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2HrvTrendData>> getV2HrvTrend(
      int? queryUserId, int intDate) async {
    var data = V2HrvTrendData();
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2LatestHrvData>> getV2LatestHrv(
      int? queryUserId, int intDate) async {
    var data = V2LatestHrvData();
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2RealtimeStressData>> getV2RealtimeStress(
      int? queryUserId, int intDate) async {
    var data = V2RealtimeStressData();
    return AppSuccess(data);
  }

  @override
  Future<AppResult<V2StressScore>> getV2StressScore(
      int? queryUserId, int intDate) async {
    var data = V2StressScore(state: 1, comprehensiveScore: 18);
    return AppSuccess(data);
  }
}