import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:get/get.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:intl/intl.dart'; import 'package:fl_chart/fl_chart.dart'; class DashboardController extends GetxController { final FirebaseFirestore _firestore = FirebaseFirestore.instance; final FirebaseAuth _auth = FirebaseAuth.instance; var totalPendapatan = 0.0.obs; var totalPendapatanCOD = 0.0.obs; var totalPendapatanNonCOD = 0.0.obs; var totalPaket = 0.obs; var totalPaketCOD = 0.obs; var totalPaketNonCOD = 0.obs; var isLoading = false.obs; var grafikPengiriman = [].obs; StreamSubscription? _listenerRealtime; @override void onInit() { super.onInit(); _listenRealtimeData(); } @override void onClose() { _listenerRealtime?.cancel(); super.onClose(); } /// 🔁 Listener realtime dashboard & grafik void _listenRealtimeData() { final user = _auth.currentUser; if (user == null) return; final userId = user.uid; // Pastikan urut berdasarkan waktu dibuat _listenerRealtime = _firestore .collection('resis') .where('store_id', isEqualTo: userId) .orderBy('created_at', descending: false) .snapshots() .listen((snapshot) { _updateDashboard(snapshot.docs); }, onError: (e) { print("🔥 Error listen data: $e"); }); } /// 🔹 Hitung ulang total dan grafik setiap ada perubahan data void _updateDashboard(List>> docs) { final now = DateTime.now(); final cutoff = now.subtract(const Duration(days: 6)); double total = 0; double totalCod = 0; double totalNonCod = 0; int paket = 0; int paketCod = 0; int paketNonCod = 0; Map pengirimanPerTanggal = {}; for (var doc in docs) { final data = doc.data(); if (data['created_at'] == null) continue; final createdAt = (data['created_at'] as Timestamp).toDate().toLocal(); final tanggalKey = DateFormat('yyyy-MM-dd').format(createdAt); // Total untuk hari ini if (createdAt.year == now.year && createdAt.month == now.month && createdAt.day == now.day) { final totalTransaksi = double.tryParse(data['total'].toString()) ?? 0; final pembayaran = data['pembayaran']?.toString().toUpperCase() ?? ''; total += totalTransaksi; paket++; if (pembayaran == 'COD') { paketCod++; totalCod += totalTransaksi; } else { paketNonCod++; totalNonCod += totalTransaksi; } } // Total pengiriman 7 hari terakhir if (!(createdAt.isBefore(cutoff) || createdAt.isAfter(now))) { pengirimanPerTanggal.update(tanggalKey, (v) => v + 1, ifAbsent: () => 1); } } // 🔸 Update data observabel totalPendapatan.value = total; totalPendapatanCOD.value = totalCod; totalPendapatanNonCOD.value = totalNonCod; totalPaket.value = paket; totalPaketCOD.value = paketCod; totalPaketNonCOD.value = paketNonCod; // 🔹 Buat data untuk 7 hari grafik final List newSpots = []; for (int i = 0; i < 7; i++) { final date = cutoff.add(Duration(days: i)); final key = DateFormat('yyyy-MM-dd').format(date); final jumlah = pengirimanPerTanggal[key] ?? 0; newSpots.add(FlSpot(i.toDouble(), jumlah.toDouble())); } // 🔸 Assign dan refresh supaya UI update langsung grafikPengiriman.assignAll(newSpots); grafikPengiriman.refresh(); print("📊 Dashboard & grafik diperbarui realtime (${DateTime.now()})"); } String formatRupiah(double value) { final format = NumberFormat.currency(locale: 'id_ID', symbol: 'Rp ', decimalDigits: 0); return format.format(value); } }