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'; class AnalisisController extends GetxController { final FirebaseFirestore _firestore = FirebaseFirestore.instance; final FirebaseAuth _auth = FirebaseAuth.instance; var monthlyData = >[].obs; var topCities = >[].obs; var selectedMonth = ''.obs; StreamSubscription? _listenerRealtime; // 🔥 simpan semua data di memory List>> _allDocs = []; @override void onInit() { super.onInit(); selectedMonth.value = DateFormat('MMM').format(DateTime.now()); _listenRealtimeData(); } @override void onClose() { _listenerRealtime?.cancel(); super.onClose(); } void _listenRealtimeData() { final user = _auth.currentUser; if (user == null) return; _listenerRealtime = _firestore .collection('resis') .where('store_id', isEqualTo: user.uid) .snapshots() .listen((snapshot) { _allDocs = snapshot.docs; _updateData(); }); } void _updateData() { final Map pengirimanPerBulan = {}; final Map> kotaSummary = {}; for (var doc in _allDocs) { final data = doc.data(); if (data['created_at'] == null || data['kota'] == null) continue; final createdAt = (data['created_at'] as Timestamp).toDate().toLocal(); final month = DateFormat('MMM').format(createdAt); final kota = data['kota'].toString(); final total = double.tryParse(data['total'].toString()) ?? 0; pengirimanPerBulan.update(month, (v) => v + 1, ifAbsent: () => 1); final key = '$month-$kota'; if (kotaSummary.containsKey(key)) { kotaSummary[key]!['transaksi'] += 1; kotaSummary[key]!['pendapatan'] += total; } else { kotaSummary[key] = { 'month': month, 'city': kota, 'transaksi': 1, 'pendapatan': total, }; } } final monthlyList = pengirimanPerBulan.entries.map((e) { return { 'month': e.key, 'pengiriman': e.value, }; }).toList() ..sort((a, b) { try { final monthA = a['month']?.toString() ?? ''; final monthB = b['month']?.toString() ?? ''; return DateFormat('MMM') .parse(monthA) .month .compareTo( DateFormat('MMM').parse(monthB).month, ); } catch (_) { return 0; } }); final kotaList = kotaSummary.values .where((k) => k['month'] == selectedMonth.value) .toList() ..sort((a, b) => (b['pendapatan'] as double).compareTo(a['pendapatan'] as double)); monthlyData.assignAll(monthlyList); // ✅ Pastikan selectedMonth valid if (monthlyList.isNotEmpty) { final months = monthlyList .map((e) => e['month'] as String) .toList(); if (!months.contains(selectedMonth.value)) { selectedMonth.value = months.first; } } topCities.assignAll(kotaList.take(10).toList()); } void setSelectedMonth(String month) { selectedMonth.value = month; _updateData(); // 🔥 INI YANG PENTING } String formatRupiah(num value) { final format = NumberFormat.currency( locale: 'id_ID', symbol: 'Rp ', decimalDigits: 0); return format.format(value); } }