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<void> saveAccountsLocally(
      List<Map<String, dynamic>> 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<List<Map<String, dynamic>>> 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<String, dynamic>)
        .toList();
  }

  /// Ambil last known good accounts (untuk fallback offline)
  static Future<List<Map<String, dynamic>>> 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<String, dynamic>)
        .toList();
  }

  /// Periksa apakah cache akun masih valid (kurang dari 24 jam untuk keandalan offline)
  static Future<bool> 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<void> clearCache() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_accountsKey);
    await prefs.remove(_lastUpdatedKey);
  }

  /// Update cache akun dari server
  static Future<void> updateAccountsFromServer(
      List<Map<String, dynamic>> accounts) async {
    await saveAccountsLocally(accounts);
  }

  /// Dapatkan akun dengan prioritas: cache valid > last known good > data server > default mapping > fallback kosong
  static Future<List<Map<String, dynamic>>> getAccountsWithFallback(
    Future<List<Map<String, dynamic>>> 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 [];
  }
}
