import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:timezone/timezone.dart' as tz; import 'package:timezone/data/latest.dart' as tz; import 'package:flutter/foundation.dart'; // For kIsWeb class NotificationService { static final NotificationService _instance = NotificationService._internal(); factory NotificationService() { return _instance; } NotificationService._internal(); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); bool _isInitialized = false; Future initialize() async { if (_isInitialized) return; // Timezone initialization if (!kIsWeb) { tz.initializeTimeZones(); } const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings( requestAlertPermission: true, requestBadgePermission: true, requestSoundPermission: true, ); // Linux initialization (optional, but good for completeness) final LinuxInitializationSettings initializationSettingsLinux = LinuxInitializationSettings(defaultActionName: 'Open notification'); final InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, macOS: initializationSettingsDarwin, linux: initializationSettingsLinux, ); await flutterLocalNotificationsPlugin.initialize( initializationSettings, onDidReceiveNotificationResponse: (NotificationResponse details) async { // Handle notification tap }, ); _isInitialized = true; } Future scheduleNotification({ required int id, required String title, required String body, required DateTime scheduledDate, }) async { if (kIsWeb) { // Web platform limitation: Background scheduling is complex. // For this demo/web preview, we'll just log it or rely on the UI confirmation. print('Web Notification Scheduled: $title - $body at $scheduledDate'); return; } await flutterLocalNotificationsPlugin.zonedSchedule( id, title, body, tz.TZDateTime.from(scheduledDate, tz.local), const NotificationDetails( android: AndroidNotificationDetails( 'pad_tracker_channel', 'Pad Tracker Reminders', channelDescription: 'Reminders to change pad/tampon', importance: Importance.max, priority: Priority.high, ), iOS: DarwinNotificationDetails(), ), androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, ); } // New method for specific notification types Future showLocalNotification({ required int id, required String title, required String body, String? channelId, String? channelName, }) async { if (kIsWeb) { print('Web Local Notification: $title - $body'); return; } const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails('tracker_general', 'General Notifications', channelDescription: 'General app notifications', importance: Importance.max, priority: Priority.high, ticker: 'ticker'); const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); await flutterLocalNotificationsPlugin .show(id, title, body, notificationDetails, payload: 'item x'); } Future showPrayerRequestNotification( {required String senderName}) async { await showLocalNotification( id: 300, title: 'New Prayer Request', body: '$senderName sent you a prayer request. Tap to pray with them.', ); } Future showTeachingPlanNotification( {required String teacherName}) async { await showLocalNotification( id: 302, title: 'New Teaching Plan', body: '$teacherName added a new teaching plan for you.', ); } Future showPartnerUpdateNotification( {required String title, required String body}) async { await showLocalNotification( id: 305, title: title, body: body, ); } Future showCycleUpdateNotification({required String message}) async { await showLocalNotification( id: 310, title: 'Cycle Update', body: message, ); } Future showSymptomNotification( {required String senderName, required String symptom}) async { await showLocalNotification( id: 315, title: 'Partner Care Reminder', body: '$senderName logged $symptom. A little extra care might be nice!', ); } Future cancelNotification(int id) async { await flutterLocalNotificationsPlugin.cancel(id); } }