import 'package:shared_preferences/shared_preferences.dart'; import 'package:travel_mate/models/checklist_item.dart'; /// Service responsible for storing and retrieving per-trip checklists. /// /// Persistence relies on `SharedPreferences` with one JSON string per trip /// key. All methods are resilient to corrupted payloads and return empty /// lists rather than throwing to keep the UI responsive. class TripChecklistService { /// Loads the checklist items for the given [tripId]. /// /// Returns an empty list if no data exists or if deserialization fails. Future> loadChecklist(String tripId) async { final prefs = await SharedPreferences.getInstance(); final raw = prefs.getString(_key(tripId)); if (raw == null) { return const []; } try { return ChecklistItem.decodeList(raw); } catch (_) { // Corrupted payload: clear it to avoid persisting errors. await prefs.remove(_key(tripId)); return const []; } } /// Persists the provided [items] list for [tripId]. /// /// This method overrides the previously stored list; use helpers like /// [addItem], [toggleItem], or [deleteItem] for incremental updates. Future saveChecklist(String tripId, List items) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_key(tripId), ChecklistItem.encodeList(items)); } /// Adds a new [item] to the checklist for [tripId]. /// /// Items are appended in creation order; the updated list is persisted. Future> addItem(String tripId, ChecklistItem item) async { final current = await loadChecklist(tripId); final updated = [...current, item]; await saveChecklist(tripId, updated); return updated; } /// Toggles the completion state of the item matching [itemId]. /// /// Returns the updated list. If the item is not found, the list is /// returned unchanged to keep UI state consistent. Future> toggleItem(String tripId, String itemId) async { final current = await loadChecklist(tripId); final updated = current .map((item) { if (item.id != itemId) { return item; } return item.copyWith(isDone: !item.isDone); }) .toList(growable: false); await saveChecklist(tripId, updated); return updated; } /// Deletes the item matching [itemId] and persists the change. Future> deleteItem(String tripId, String itemId) async { final current = await loadChecklist(tripId); final updated = current.where((item) => item.id != itemId).toList(); await saveChecklist(tripId, updated); return updated; } String _key(String tripId) => 'checklist_$tripId'; }