import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import '../models/firefly_account.dart';

class AccountMirrorService {
  static const String _accountsKey = 'mirrored_accounts';
  static const String _lastSyncKey = 'accounts_last_sync';
  static const String _lastSyncTimeKey = 'accounts_last_sync_time';

  /// Simpan semua akun ke local storage untuk offline usage
  static Future<void> mirrorAccounts(List<FireflyAccount> accounts) async {
    final prefs = await SharedPreferences.getInstance();

    // Konversi akun ke JSON string
    final accountsJson = accounts.map((account) => account.toJson()).toList();

    await prefs.setStringList(
        _accountsKey, accountsJson.map((json) => jsonEncode(json)).toList());
    await prefs.setInt(_lastSyncTimeKey, DateTime.now().millisecondsSinceEpoch);
    await prefs.setBool(
        _lastSyncKey, true); // Menandakan bahwa akun pernah di-sync
  }

  /// Ambil semua akun yang telah di-mirror dari local storage
  static Future<List<FireflyAccount>> getMirroredAccounts() async {
    final prefs = await SharedPreferences.getInstance();
    final accountsJsonList = prefs.getStringList(_accountsKey) ?? [];

    if (accountsJsonList.isEmpty) {
      return [];
    }

    return accountsJsonList
        .map((jsonString) => FireflyAccount.fromJson(json.decode(jsonString)))
        .toList();
  }

  /// Ambil akun berdasarkan tipe (revenue, asset, dll)
  static Future<List<FireflyAccount>> getMirroredAccountsByType(
      String type) async {
    final allAccounts = await getMirroredAccounts();
    return allAccounts.where((account) => account.type == type).toList();
  }

  /// Ambil akun berdasarkan ID
  static Future<FireflyAccount?> getAccountById(String id) async {
    final allAccounts = await getMirroredAccounts();
    return allAccounts.firstWhere(
      (account) => account.id == id,
      orElse: () => FireflyAccount(id: '', name: '', type: ''),
    );
  }

  /// Periksa apakah akun sudah pernah di-mirror
  static Future<bool> hasMirroredAccounts() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.containsKey(_accountsKey);
  }

  /// Ambil waktu terakhir sync
  static Future<DateTime?> getLastSyncTime() async {
    final prefs = await SharedPreferences.getInstance();
    final timestamp = prefs.getInt(_lastSyncTimeKey);
    return timestamp != null
        ? DateTime.fromMillisecondsSinceEpoch(timestamp)
        : null;
  }

  /// Ambil status sync terakhir
  static Future<bool> getLastSyncStatus() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool(_lastSyncKey) ?? false;
  }

  /// Hapus semua data mirror (untuk testing atau reset)
  static Future<void> clearMirror() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_accountsKey);
    await prefs.remove(_lastSyncTimeKey);
    await prefs.remove(_lastSyncKey);
  }

  /// Update mirror dari server dan simpan ke local storage
  static Future<void> updateMirrorFromServer(
      List<FireflyAccount> accounts) async {
    await mirrorAccounts(accounts);
  }

  /// Dapatkan akun dengan prioritas: mirror terbaru > empty list
  static Future<List<FireflyAccount>> getAccountsWithFallback(
    Future<List<FireflyAccount>> Function() serverFetchFunction,
  ) async {
    // Coba ambil dari mirror terlebih dahulu
    final mirroredAccounts = await getMirroredAccounts();
    if (mirroredAccounts.isNotEmpty) {
      return mirroredAccounts;
    }

    // Jika mirror kosong, coba ambil dari server dan mirror
    try {
      final serverAccounts = await serverFetchFunction();
      if (serverAccounts.isNotEmpty) {
        // Simpan ke mirror jika berhasil ambil dari server
        await updateMirrorFromServer(serverAccounts);
        return serverAccounts;
      }
    } catch (e) {
      print('Gagal mengambil akun dari server: $e');
    }

    // Jika semua gagal, kembalikan empty list
    return [];
  }

  /// Format waktu sync untuk display
  static String formatSyncTime(DateTime? syncTime) {
    if (syncTime == null) {
      return 'Belum pernah disinkronisasi';
    }

    final now = DateTime.now();
    final difference = now.difference(syncTime);

    if (difference.inMinutes < 1) {
      return 'Baru saja';
    } else if (difference.inHours < 1) {
      final minutes = difference.inMinutes;
      return '$minutes menit yang lalu';
    } else if (difference.inDays < 1) {
      final hours = difference.inHours;
      return '$hours jam yang lalu';
    } else {
      final days = difference.inDays;
      return '$days hari yang lalu';
    }
  }

  /// Sinkronisasi otomatis jika server tersedia
  static Future<bool> autoSyncIfNeeded(
    Future<List<FireflyAccount>> Function() serverFetchFunction,
  ) async {
    try {
      final serverAccounts = await serverFetchFunction();
      if (serverAccounts.isNotEmpty) {
        await updateMirrorFromServer(serverAccounts);
        return true;
      }
    } catch (e) {
      print('Auto sync gagal: $e');
      return false;
    }
    return false;
  }
}
