CoffeeAtHome/lib/providers/app_state.dart
2026-03-29 08:13:38 -07:00

349 lines
9.5 KiB
Dart

import 'package:flutter/foundation.dart';
import '../models/bean.dart';
import '../models/machine.dart';
import '../models/recipe.dart';
import '../models/drink.dart';
import '../models/journal_entry.dart';
import '../services/storage_service.dart';
import '../services/data_seeding_service.dart';
class AppState extends ChangeNotifier {
final StorageService _storageService = StorageService();
final DataSeedingService _dataSeedingService = DataSeedingService();
List<Bean> _beans = [];
List<Machine> _machines = [];
List<Recipe> _recipes = [];
List<Drink> _drinks = [];
List<JournalEntry> _journalEntries = [];
bool _isLoading = false;
// Getters
List<Bean> get beans => _beans;
List<Machine> get machines => _machines;
List<Recipe> get recipes => _recipes;
List<Drink> get drinks => _drinks;
List<JournalEntry> get journalEntries => _journalEntries;
bool get isLoading => _isLoading;
// Preferred items
List<Bean> get preferredBeans =>
_beans.where((bean) => bean.preferred).toList();
List<Drink> get preferredDrinks =>
_drinks.where((drink) => drink.preferred).toList();
AppState() {
_loadData();
}
Future<void> _loadData() async {
_setLoading(true);
try {
// Seed initial data if needed (loads from CSV files)
await _dataSeedingService.seedInitialData();
_beans = await _storageService.getBeans();
_machines = await _storageService.getMachines();
_recipes = await _storageService.getRecipes();
_drinks = await _storageService.getDrinks();
_journalEntries = await _storageService.getJournalEntries();
} catch (e) {
debugPrint('Error loading data: $e');
} finally {
_setLoading(false);
}
}
void _setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
// Bean operations
Future<void> addBean(Bean bean) async {
try {
await _storageService.saveBean(bean);
// Reload beans from storage to keep data consistent
_beans = await _storageService.getBeans();
notifyListeners();
} catch (e) {
debugPrint('Error adding bean: $e');
rethrow;
}
}
Future<void> updateBean(Bean bean) async {
try {
await _storageService.saveBean(bean);
// Reload beans from storage to keep data consistent
_beans = await _storageService.getBeans();
notifyListeners();
} catch (e) {
debugPrint('Error updating bean: $e');
rethrow;
}
}
Future<void> deleteBean(String id) async {
try {
await _storageService.deleteBean(id);
// Reload beans from storage to keep data consistent
_beans = await _storageService.getBeans();
notifyListeners();
} catch (e) {
debugPrint('Error deleting bean: $e');
rethrow;
}
}
// Machine operations
Future<void> addMachine(Machine machine) async {
try {
await _storageService.saveMachine(machine);
// Reload machines from storage to keep data consistent
_machines = await _storageService.getMachines();
notifyListeners();
} catch (e) {
debugPrint('Error adding machine: $e');
rethrow;
}
}
Future<void> updateMachine(Machine machine) async {
try {
await _storageService.saveMachine(machine);
// Reload machines from storage to keep data consistent
_machines = await _storageService.getMachines();
notifyListeners();
} catch (e) {
debugPrint('Error updating machine: $e');
rethrow;
}
}
Future<void> deleteMachine(String id) async {
try {
await _storageService.deleteMachine(id);
// Reload machines from storage to keep data consistent
_machines = await _storageService.getMachines();
notifyListeners();
} catch (e) {
debugPrint('Error deleting machine: $e');
rethrow;
}
}
// Recipe operations
Future<void> addRecipe(Recipe recipe) async {
try {
await _storageService.saveRecipe(recipe);
// Reload recipes from storage to keep data consistent
_recipes = await _storageService.getRecipes();
notifyListeners();
} catch (e) {
debugPrint('Error adding recipe: $e');
rethrow;
}
}
Future<void> updateRecipe(Recipe recipe) async {
try {
await _storageService.saveRecipe(recipe);
// Reload recipes from storage to keep data consistent
_recipes = await _storageService.getRecipes();
notifyListeners();
} catch (e) {
debugPrint('Error updating recipe: $e');
rethrow;
}
}
Future<void> deleteRecipe(String id) async {
try {
await _storageService.deleteRecipe(id);
// Reload recipes from storage to keep data consistent
_recipes = await _storageService.getRecipes();
notifyListeners();
} catch (e) {
debugPrint('Error deleting recipe: $e');
rethrow;
}
}
// Drink operations
Future<void> addDrink(Drink drink) async {
try {
await _storageService.saveDrink(drink);
// Reload drinks from storage to keep data consistent
_drinks = await _storageService.getDrinks();
notifyListeners();
} catch (e) {
debugPrint('Error adding drink: $e');
rethrow;
}
}
Future<void> updateDrink(Drink drink) async {
try {
await _storageService.saveDrink(drink);
// Reload drinks from storage to keep data consistent
_drinks = await _storageService.getDrinks();
notifyListeners();
} catch (e) {
debugPrint('Error updating drink: $e');
rethrow;
}
}
Future<void> deleteDrink(String id) async {
try {
await _storageService.deleteDrink(id);
// Reload drinks from storage to keep data consistent
_drinks = await _storageService.getDrinks();
notifyListeners();
} catch (e) {
debugPrint('Error deleting drink: $e');
rethrow;
}
}
// Journal operations
Future<void> addJournalEntry(JournalEntry entry) async {
try {
await _storageService.saveJournalEntry(entry);
// Reload journal entries from storage to keep data consistent
_journalEntries = await _storageService.getJournalEntries();
notifyListeners();
} catch (e) {
debugPrint('Error adding journal entry: $e');
rethrow;
}
}
Future<void> updateJournalEntry(JournalEntry entry) async {
try {
await _storageService.saveJournalEntry(entry);
// Reload journal entries from storage to keep data consistent
_journalEntries = await _storageService.getJournalEntries();
notifyListeners();
} catch (e) {
debugPrint('Error updating journal entry: $e');
rethrow;
}
}
Future<void> deleteJournalEntry(String id) async {
try {
await _storageService.deleteJournalEntry(id);
// Reload journal entries from storage to keep data consistent
_journalEntries = await _storageService.getJournalEntries();
notifyListeners();
} catch (e) {
debugPrint('Error deleting journal entry: $e');
rethrow;
}
}
// Search functionality
List<dynamic> searchAll(String query) {
final lowerQuery = query.toLowerCase();
final results = <dynamic>[];
// Search beans
results.addAll(
_beans.where(
(bean) =>
bean.name.toLowerCase().contains(lowerQuery) ||
bean.varietal.toLowerCase().contains(lowerQuery) ||
bean.originCountry?.details.toLowerCase().contains(lowerQuery) ==
true,
),
);
// Search machines
results.addAll(
_machines.where(
(machine) =>
machine.manufacturer.toLowerCase().contains(lowerQuery) ||
machine.model.toLowerCase().contains(lowerQuery) ||
machine.details.toLowerCase().contains(lowerQuery),
),
);
// Search recipes
results.addAll(
_recipes.where(
(recipe) =>
recipe.name.toLowerCase().contains(lowerQuery) ||
recipe.instructions.toLowerCase().contains(lowerQuery) ||
recipe.notes?.toLowerCase().contains(lowerQuery) == true,
),
);
// Search drinks
results.addAll(
_drinks.where(
(drink) =>
drink.name.toLowerCase().contains(lowerQuery) ||
drink.details.toLowerCase().contains(lowerQuery) ||
drink.notes.toLowerCase().contains(lowerQuery),
),
);
return results;
}
// Clear all data
Future<void> clearAllData() async {
await _storageService.clearAllData();
_beans.clear();
_machines.clear();
_recipes.clear();
_drinks.clear();
_journalEntries.clear();
notifyListeners();
}
// Clear and reseed data for testing
Future<void> clearAndReseedData() async {
_setLoading(true);
try {
await _dataSeedingService.clearAndReseedData();
await _loadData();
} catch (e) {
debugPrint('Error reseeding data: $e');
} finally {
_setLoading(false);
}
}
// Catalog browsing operations
Future<List<Bean>> getAllAvailableBeans() async {
try {
return await _storageService.getAllAvailableBeans();
} catch (e) {
debugPrint('Error loading available beans: $e');
return [];
}
}
Future<List<Machine>> getAllAvailableMachines() async {
try {
return await _storageService.getAllAvailableMachines();
} catch (e) {
debugPrint('Error loading available machines: $e');
return [];
}
}
Future<List<Recipe>> getAllAvailableRecipes() async {
try {
return await _storageService.getAllAvailableRecipes();
} catch (e) {
debugPrint('Error loading available recipes: $e');
return [];
}
}
}