// lib/app/modules/notification/controllers/notification_controller.dart import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import '../../../services/firestore_service.dart'; import '../../../models/notification_model.dart'; import '../../../models/patient_model.dart'; import '../../../models/room_model.dart'; class NotificationItem { final String id; final String title; final String message; final String room; final String patientName; final DateTime time; final String deviceId; final bool isRead; NotificationItem({ required this.id, required this.title, required this.message, required this.room, required this.deviceId, required this.patientName, required this.time, this.isRead = false, }); NotificationItem copyWith({ String? id, String? title, String? message, String? room, String? patientName, DateTime? time, String? deviceId, bool? isRead, }) { return NotificationItem( id: id ?? this.id, title: title ?? this.title, message: message ?? this.message, room: room ?? this.room, deviceId: deviceId ?? this.deviceId, patientName: patientName ?? this.patientName, time: time ?? this.time, isRead: isRead ?? this.isRead, ); } } class NotificationController extends GetxController { final FirestoreService _firestoreService = FirestoreService(); final selectedTab = 0.obs; final _allNotifications = [].obs; final isLoading = true.obs; StreamSubscription? _notificationsSubscription; @override void onInit() { super.onInit(); _initializeNotifications(); } @override void onClose() { _notificationsSubscription?.cancel(); super.onClose(); } /// Initialize notifications dari Firestore void _initializeNotifications() { isLoading.value = true; _notificationsSubscription = _firestoreService .getNotificationsStream() .listen((notificationModels) async { final List items = []; for (var notifModel in notificationModels) { // Get patient info final patient = await _firestoreService.getPatientById( notifModel.patientId, ); // Get room name from patient's roomId String roomName = 'Unknown Room'; if (patient != null && patient.roomId.isNotEmpty) { final rooms = await _firestoreService.getRoomsStream().first; final room = rooms.firstWhereOrNull( (r) => r.roomName.toLowerCase() == patient.roomId.toLowerCase(), ); roomName = room?.roomName ?? patient.roomId; } items.add( NotificationItem( id: notifModel.id, title: notifModel.title, message: notifModel.message, room: roomName, deviceId: notifModel.deviceId, patientName: patient?.namePatient ?? 'Unknown Patient', time: notifModel.createdAt, isRead: notifModel.isRead, ), ); } _allNotifications.value = items; isLoading.value = false; }, onError: (error) { print('Error listening to notifications: $error'); isLoading.value = false; }); } // Computed property untuk notifikasi yang difilter List get notifications { if (selectedTab.value == 0) { // Tab "Baru" - notifikasi yang belum dibaca return _allNotifications.where((notif) => !notif.isRead).toList(); } else { // Tab "Sudah dibaca" - notifikasi yang sudah dibaca return _allNotifications.where((notif) => notif.isRead).toList(); } } void changeTab(int index) { selectedTab.value = index; } Future deleteNotification(String id) async { try { await _firestoreService.deleteNotification(id); // Local update akan dilakukan otomatis oleh stream } catch (e) { Get.snackbar( 'Error', 'Gagal menghapus notifikasi: $e', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.redAccent, colorText: Colors.white, margin: const EdgeInsets.all(16), ); } } Future markAsRead(String id) async { try { await _firestoreService.markNotificationAsRead(id); // Local update akan dilakukan otomatis oleh stream } catch (e) { Get.snackbar( 'Error', 'Gagal menandai notifikasi: $e', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.redAccent, colorText: Colors.white, margin: const EdgeInsets.all(16), ); } } String getTimeAgo(DateTime time) { final difference = DateTime.now().difference(time); if (difference.inMinutes < 60) { return '${difference.inMinutes}min ago'; } else if (difference.inHours < 24) { return '${difference.inHours}h ago'; } else { return '${difference.inDays}d ago'; } } // Method untuk menghitung jumlah notifikasi baru int get unreadCount { return _allNotifications.where((notif) => !notif.isRead).length; } /// Method untuk menambahkan notifikasi baru (bisa dipanggil dari monitoring) Future addNotification({ required String patientId, required String deviceId, required String title, required String message, }) async { try { final notification = NotificationModel( id: '', // Will be auto-generated by Firestore patientId: patientId, deviceId: deviceId, title: title, message: message, isRead: false, createdAt: DateTime.now(), ); await _firestoreService.addNotification(notification); } catch (e) { print('Error adding notification: $e'); } } }