import 'package:flutter/foundation.dart'; import '../models/account.dart'; import '../models/event.dart'; import '../services/api_service.dart'; import '../services/auth_service.dart'; import '../services/schedule_cache_service.dart'; class ScheduleProvider extends ChangeNotifier { final ApiService _apiService; final AuthService _authService = AuthService(); final ScheduleCacheService _cacheService = ScheduleCacheService(); List accounts = []; List events = []; String? selectedAccount; String? selectedAgegroup; String? selectedSubgroup; bool isLoading = false; bool isRefreshing = false; String? error; DateTime? lastUpdated; ScheduleProvider(this._apiService); Future loadAccounts() async { try { accounts = await _apiService.getAccounts(); final storedAccount = await _authService.getStoredAccount(); selectedAccount = storedAccount; if (selectedAccount == null || !accounts.any((a) => a.name == selectedAccount)) { if (accounts.isNotEmpty) { selectedAccount = accounts.first.name; } } // Restore persisted filters for selected account if (selectedAccount != null) { final (cachedAgegroup, cachedSubgroup) = await _cacheService.loadFilters(selectedAccount!); selectedAgegroup = cachedAgegroup; selectedSubgroup = cachedSubgroup; } notifyListeners(); } catch (e) { error = 'Failed to load accounts: $e'; notifyListeners(); } } Future loadCachedSchedule() async { if (selectedAccount == null) return; isLoading = true; error = null; notifyListeners(); try { final cachedEvents = await _cacheService.loadEvents(selectedAccount!); if (cachedEvents != null) { events = cachedEvents.where((e) => e.eventType == 'Jeu').toList(); lastUpdated = await _cacheService.getLastUpdated(selectedAccount!); } else { events = []; } isLoading = false; notifyListeners(); // Auto-refresh on first run if cache is empty if (events.isEmpty) { await refreshSchedule(); } } catch (e) { isLoading = false; error = 'Failed to load cached schedule: $e'; notifyListeners(); } } Future refreshSchedule() async { if (selectedAccount == null) return; isRefreshing = true; error = null; notifyListeners(); try { final allEvents = await _apiService.getSchedule(selectedAccount!); events = allEvents.where((e) => e.eventType == 'Jeu').toList(); // Cache for this account await _cacheService.saveEvents(selectedAccount!, allEvents); lastUpdated = DateTime.now(); } catch (e) { error = 'Failed to refresh schedule: $e'; } finally { isRefreshing = false; notifyListeners(); } } Future setAccount(String account) async { selectedAccount = account; await _authService.setAccount(account); // Restore filters for this account final (cachedAgegroup, cachedSubgroup) = await _cacheService.loadFilters(account); selectedAgegroup = cachedAgegroup; selectedSubgroup = cachedSubgroup; notifyListeners(); // Load cached schedule for this account, or auto-refresh if empty await loadCachedSchedule(); } Future setAgegroup(String? agegroup) async { selectedAgegroup = agegroup; selectedSubgroup = null; if (selectedAccount != null) { await _cacheService.saveFilters( selectedAccount!, selectedAgegroup, selectedSubgroup, ); } notifyListeners(); } Future setSubgroup(String? subgroup) async { selectedSubgroup = subgroup; if (selectedAccount != null) { await _cacheService.saveFilters( selectedAccount!, selectedAgegroup, selectedSubgroup, ); } notifyListeners(); } Future clearCache() async { await _cacheService.clearAllCache(); } List get filteredEvents { return events.where((event) { if (selectedAgegroup != null && event.agegroup != selectedAgegroup) { return false; } if (selectedSubgroup != null) { final subgroup = _extractSubgroup(event.name); if (subgroup != selectedSubgroup) { return false; } } return true; }).toList(); } List get agegroups { return events.map((e) => e.agegroup).toSet().toList()..sort(); } List get subgroups { if (selectedAgegroup == null) return []; return events .where((e) => e.agegroup == selectedAgegroup) .map((e) => _extractSubgroup(e.name)) .toSet() .toList() ..sort(); } String _extractSubgroup(String name) { final parts = name.split(' - '); if (parts.length > 1) { parts.removeLast(); // Remove opponent return parts.join(' - '); } return name; } }