import 'dart:convert'; import 'package:workmanager/workmanager.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:odoo_rpc/odoo_rpc.dart'; import 'notification_service.dart'; // NOTE: This key tracks what IDs have been shown as device tray notifications. // It is separate from 'last_seen_notification_id' (which tracks what the user READ in-app). const String _kLastDeviceNotifiedId = 'last_device_notified_id'; @pragma('vm:entry-point') void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { try { final prefs = await SharedPreferences.getInstance(); final url = prefs.getString('odoo_url'); final sessionStr = prefs.getString('odoo_session'); if (url == null || sessionStr == null) { return Future.value(true); // Not logged in, nothing to do } final lastDeviceNotifiedId = prefs.getInt(_kLastDeviceNotifiedId) ?? 0; final sessionArgs = json.decode(sessionStr); final session = OdooSession.fromJson( Map.from(sessionArgs as Map)); final client = OdooClient(url, sessionId: session); final response = await client.callRPC( '/api/loyalty/fetch_notifications', 'call', {'last_id': 0}, ); client.close(); if (response != null && response['status'] == 'success') { final List notifications = List.from(response['data'] ?? []); // Filter to only truly new ones not yet shown on device tray final newNotifs = notifications .where((n) => (n['id'] as int? ?? 0) > lastDeviceNotifiedId) .toList(); final notifService = NotificationService(); await notifService.initialize(); if (newNotifs.isNotEmpty) { int highestId = lastDeviceNotifiedId; for (final notif in newNotifs) { final int notifId = notif['id'] as int? ?? 0; if (notifId > highestId) highestId = notifId; await notifService.showNotification( id: notifId, title: notif['title'] as String? ?? 'Mie Mapan', body: notif['body'] as String? ?? '', ); } await prefs.setInt(_kLastDeviceNotifiedId, highestId); } // Always compute badge count based on read_notification_ids final readIds = prefs.getStringList('read_notification_ids'); if (readIds == null) { // Initialize read list with all currently fetched notifications on first install/run final initialRead = notifications.map((n) => (n['id'] as int? ?? 0).toString()).toList(); await prefs.setStringList('read_notification_ids', initialRead); await notifService.setBadge(0); } else { final unreadCount = notifications .where((n) => !readIds.contains((n['id'] as int? ?? 0).toString())) .length; await notifService.setBadge(unreadCount); } } } catch (_) { // Silently swallow — background isolate must never crash } return Future.value(true); }); }