import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; class AccountCacheService { static const String _accountsKey = 'cached_accounts'; static const String _lastUpdatedKey = 'accounts_last_updated'; static const String _lastKnownGoodAccountsKey = 'last_known_good_accounts'; /// Simpan akun ke cache lokal (cache utama) static Future saveAccountsLocally( List> accounts) async { final prefs = await SharedPreferences.getInstance(); // Konversi akun ke JSON string final accountsJson = accounts.map((account) => json.encode(account)).toList(); await prefs.setStringList(_accountsKey, accountsJson); await prefs.setInt(_lastUpdatedKey, DateTime.now().millisecondsSinceEpoch); // Simpan juga sebagai last known good accounts await prefs.setStringList(_lastKnownGoodAccountsKey, accountsJson); } /// Ambil akun dari cache utama static Future>> getCachedAccounts() async { final prefs = await SharedPreferences.getInstance(); final accountsJsonList = prefs.getStringList(_accountsKey) ?? []; if (accountsJsonList.isEmpty) { return []; } return accountsJsonList .map((jsonString) => json.decode(jsonString) as Map) .toList(); } /// Ambil last known good accounts (untuk fallback offline) static Future>> getLastKnownGoodAccounts() async { final prefs = await SharedPreferences.getInstance(); final accountsJsonList = prefs.getStringList(_lastKnownGoodAccountsKey) ?? []; if (accountsJsonList.isEmpty) { return []; } return accountsJsonList .map((jsonString) => json.decode(jsonString) as Map) .toList(); } /// Periksa apakah cache akun masih valid (kurang dari 24 jam untuk keandalan offline) static Future isCacheValid() async { final prefs = await SharedPreferences.getInstance(); final lastUpdated = prefs.getInt(_lastUpdatedKey) ?? 0; final now = DateTime.now().millisecondsSinceEpoch; // Cache valid selama 24 jam (86400000 ms) - lebih lama untuk mendukung offline return (now - lastUpdated) < 8640000; } /// Hapus cache akun static Future clearCache() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove(_accountsKey); await prefs.remove(_lastUpdatedKey); } /// Update cache akun dari server static Future updateAccountsFromServer( List> accounts) async { await saveAccountsLocally(accounts); } /// Dapatkan akun dengan prioritas: cache valid > last known good > data server > default mapping > fallback kosong static Future>> getAccountsWithFallback( Future>> Function() serverFetchFunction, ) async { // 1. Coba ambil dari cache valid dulu if (await isCacheValid()) { final cachedAccounts = await getCachedAccounts(); if (cachedAccounts.isNotEmpty) { return cachedAccounts; } } // 2. Coba ambil dari last known good accounts (offline fallback) final lastKnownGoodAccounts = await getLastKnownGoodAccounts(); if (lastKnownGoodAccounts.isNotEmpty) { return lastKnownGoodAccounts; } // 3. Jika cache tidak valid atau kosong, coba ambil dari server try { final serverAccounts = await serverFetchFunction(); if (serverAccounts.isNotEmpty) { // Simpan ke cache jika berhasil ambil dari server await updateAccountsFromServer(serverAccounts); return serverAccounts; } } catch (e) { print('Gagal mengambil akun dari server: $e'); } // 4. Jika semua gagal, kembalikan last known good accounts (meskipun mungkin expired) final fallbackAccounts = await getLastKnownGoodAccounts(); if (fallbackAccounts.isNotEmpty) { return fallbackAccounts; } // 5. Jika tetap kosong, kembalikan empty list return []; } }