import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../features/scan/recognition_service.dart'; import '../../shared/models/home_summary.dart'; import '../../shared/models/menu.dart'; import '../menu/menu_provider.dart'; import 'home_service.dart'; // ── Selected date (persists while app is open) ──────────────── /// The date currently viewed on the home screen. /// Defaults to today; can be changed via the date selector. final selectedDateProvider = StateProvider((ref) => DateTime.now()); /// Formats a [DateTime] to the 'YYYY-MM-DD' string expected by the diary API. String formatDateForDiary(DateTime date) => '${date.year}-${date.month.toString().padLeft(2, '0')}-' '${date.day.toString().padLeft(2, '0')}'; // ── Home summary ────────────────────────────────────────────── class HomeNotifier extends StateNotifier> { final HomeService _service; HomeNotifier(this._service) : super(const AsyncValue.loading()) { load(); } Future load() async { state = const AsyncValue.loading(); state = await AsyncValue.guard(() => _service.getSummary()); } } final homeProvider = StateNotifierProvider>( (ref) => HomeNotifier(ref.read(homeServiceProvider)), ); // ── Today's unlinked recognition jobs ───────────────────────── class TodayJobsNotifier extends StateNotifier>> { final RecognitionService _service; TodayJobsNotifier(this._service) : super(const AsyncValue.loading()) { load(); } Future load() async { state = const AsyncValue.loading(); state = await AsyncValue.guard(() => _service.listTodayUnlinkedJobs()); } } final todayJobsProvider = StateNotifierProvider>>( (ref) => TodayJobsNotifier(ref.read(recognitionServiceProvider)), ); // ── All recognition jobs (history screen) ───────────────────── class AllJobsNotifier extends StateNotifier>> { final RecognitionService _service; AllJobsNotifier(this._service) : super(const AsyncValue.loading()) { load(); } Future load() async { state = const AsyncValue.loading(); state = await AsyncValue.guard(() => _service.listAllJobs()); } } final allJobsProvider = StateNotifierProvider>>( (ref) => AllJobsNotifier(ref.read(recognitionServiceProvider)), ); // ── Planned meals from menu ──────────────────────────────────── /// Returns planned [MealSlot]s from the menu plan for [dateString]. /// Derives from the already-cached weekly menu — no extra network call. /// Returns an empty list when no plan exists for that week. final plannedMealsProvider = Provider.family, String>((ref, dateString) { final date = DateTime.parse(dateString); final weekString = isoWeekString(date); final menuState = ref.watch(menuProvider(weekString)); final plan = menuState.valueOrNull; if (plan == null) return []; for (final day in plan.days) { if (day.date == dateString) return day.meals; } return []; });