import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:uuid/uuid.dart'; import '../models/fuel_entry.dart'; import '../models/vehicle.dart'; import 'storage_service.dart'; /// Single source of truth for the app's in-memory data (vehicles + fuel /// entries), backed by [StorageService] for persistence. Screens read from /// this via Provider and call its mutating methods, which take care of /// writing through to disk and notifying listeners. class AppState extends ChangeNotifier { final StorageService storage = StorageService(); final _uuid = const Uuid(); List vehicles = []; List fuelEntries = []; bool isLoading = true; Future init() async { await storage.init(); final data = await storage.loadData(); vehicles = data.vehicles; fuelEntries = data.entries; isLoading = false; notifyListeners(); } Future addVehicle({ required String make, required String model, required String color, required String licensePlate, }) async { vehicles.add(Vehicle( id: _uuid.v4(), make: make, model: model, color: color, licensePlate: licensePlate, )); await _persist(); } Future updateVehicle(Vehicle updated) async { final index = vehicles.indexWhere((v) => v.id == updated.id); if (index != -1) { vehicles[index] = updated; await _persist(); } } Future deleteVehicle(String vehicleId) async { for (final entry in fuelEntries.where((e) => e.vehicleId == vehicleId)) { await storage.deleteReceiptImage(entry.receiptImagePath); } fuelEntries.removeWhere((e) => e.vehicleId == vehicleId); vehicles.removeWhere((v) => v.id == vehicleId); await _persist(); } Future addFuelEntry({ required String vehicleId, required DateTime date, required double gallons, required double pricePerGallon, required double totalCost, File? receiptImage, }) async { final id = _uuid.v4(); String? storedImagePath; if (receiptImage != null) { storedImagePath = await storage.storeReceiptImage(receiptImage, id); } final entry = FuelEntry( id: id, vehicleId: vehicleId, date: date, gallons: gallons, pricePerGallon: pricePerGallon, totalCost: totalCost, receiptImagePath: storedImagePath, ); fuelEntries.add(entry); await _persist(); return entry; } Future deleteFuelEntry(String entryId) async { final entry = fuelEntries.firstWhere((e) => e.id == entryId); await storage.deleteReceiptImage(entry.receiptImagePath); fuelEntries.removeWhere((e) => e.id == entryId); await _persist(); } List entriesForVehicle(String vehicleId) { final list = fuelEntries.where((e) => e.vehicleId == vehicleId).toList(); list.sort((a, b) => b.date.compareTo(a.date)); return list; } double totalGallonsForVehicle(String vehicleId) => fuelEntries .where((e) => e.vehicleId == vehicleId) .fold(0.0, (sum, e) => sum + e.gallons); double get totalGallonsAllVehicles => fuelEntries.fold(0.0, (sum, e) => sum + e.gallons); Vehicle? vehicleById(String id) { try { return vehicles.firstWhere((v) => v.id == id); } catch (_) { return null; } } Future changeSaveDirectory(String newPath) async { await storage.setSaveDirectory(newPath); notifyListeners(); } Future _persist() async { await storage.saveData(vehicles: vehicles, entries: fuelEntries); notifyListeners(); } }