LifeFlow/android/lib/repositories/routine_repository.dart

121 lines
3.6 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive/hive.dart';
import '../models/routine.dart';
final routineRepositoryProvider = Provider<RoutineRepository>((ref) {
return RoutineRepository();
});
final routinesProvider = StreamProvider<List<Routine>>((ref) {
final repository = ref.watch(routineRepositoryProvider);
return repository.watchAllRoutines();
});
final todayRoutinesProvider = FutureProvider<List<Routine>>((ref) async {
final repository = ref.watch(routineRepositoryProvider);
return repository.getTodaysRoutines();
});
class RoutineRepository {
static const String _boxName = 'routines';
Box<Routine>? _box;
Future<Box<Routine>> _getBox() async {
_box ??= await Hive.openBox<Routine>(_boxName);
return _box!;
}
// Create
Future<void> createRoutine(Routine routine) async {
final box = await _getBox();
await box.put(routine.id, routine);
}
// Read
Future<Routine?> getRoutine(String id) async {
final box = await _getBox();
return box.get(id);
}
Future<List<Routine>> getAllRoutines() async {
final box = await _getBox();
return box.values.toList();
}
Stream<List<Routine>> watchAllRoutines() async* {
final box = await _getBox();
yield box.values.toList();
yield* box.watch().map((_) => box.values.toList());
}
Future<List<Routine>> getRoutinesByCategory(RoutineCategory category) async {
final routines = await getAllRoutines();
return routines.where((r) => r.category == category).toList();
}
Future<List<Routine>> getTodaysRoutines() async {
final routines = await getAllRoutines();
final now = DateTime.now();
final weekday = now.weekday - 1; // 0 = Monday, 6 = Sunday
return routines.where((routine) {
if (!routine.isActive) return false;
switch (routine.schedule.type) {
case ScheduleType.daily:
return true;
case ScheduleType.weekly:
return routine.schedule.daysOfWeek?.contains(weekday) ?? false;
case ScheduleType.specificDate:
final specificDate = routine.schedule.specificDate;
if (specificDate == null) return false;
return specificDate.year == now.year &&
specificDate.month == now.month &&
specificDate.day == now.day;
case ScheduleType.interval:
// Simplified: check if today falls on interval
final createdDate = DateTime(
routine.createdAt.year,
routine.createdAt.month,
routine.createdAt.day,
);
final today = DateTime(now.year, now.month, now.day);
final daysDiff = today.difference(createdDate).inDays;
final interval = routine.schedule.intervalDays ?? 1;
return daysDiff % interval == 0;
}
}).toList();
}
// Update
Future<void> updateRoutine(Routine routine) async {
final box = await _getBox();
await box.put(routine.id, routine.copyWith(updatedAt: DateTime.now()));
}
Future<void> toggleRoutineActive(String id) async {
final routine = await getRoutine(id);
if (routine != null) {
await updateRoutine(routine.copyWith(isActive: !routine.isActive));
}
}
// Delete
Future<void> deleteRoutine(String id) async {
final box = await _getBox();
await box.delete(id);
}
// Statistics
Future<Map<RoutineCategory, int>> getRoutineCountsByCategory() async {
final routines = await getAllRoutines();
final counts = <RoutineCategory, int>{};
for (final routine in routines) {
counts[routine.category] = (counts[routine.category] ?? 0) + 1;
}
return counts;
}
}