import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:timezone/timezone.dart' as tz; import 'package:timezone/data/latest_all.dart' as tz; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; class NotificationService { static final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); /// Initialisation (à appeler dans main()) static Future initialize() async { tz.initializeTimeZones(); const AndroidInitializationSettings androidInitSettings = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings( android: androidInitSettings, iOS: DarwinInitializationSettings(), ); await _notificationsPlugin.initialize(initSettings); // Demande les permissions au lancement await requestPermissions(); } /// Demander les permissions (Android 13+ et iOS) static Future requestPermissions() async { // Android 13+ final androidImplementation = _notificationsPlugin.resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>(); await androidImplementation?.requestNotificationsPermission(); // iOS final iosImplementation = _notificationsPlugin.resolvePlatformSpecificImplementation< IOSFlutterLocalNotificationsPlugin>(); await iosImplementation?.requestPermissions( alert: true, badge: true, sound: true, ); } /// Planifie une notification 1h avant l’évènement static Future scheduleEventNotification({ required String eventId, required String title, required String body, required DateTime eventDate, }) async { final scheduledDate = eventDate.subtract(const Duration(hours: 1)); if (scheduledDate.isBefore(DateTime.now())) { // Trop tard pour notifier return; } await _notificationsPlugin.zonedSchedule( eventId.hashCode, // identifiant unique pour l’évènement title, body, tz.TZDateTime.from(scheduledDate, tz.local), const NotificationDetails( android: AndroidNotificationDetails( 'events_channel', 'Events', channelDescription: 'Favorite event notifications', importance: Importance.high, priority: Priority.high, ), iOS: DarwinNotificationDetails(), ), androidScheduleMode: AndroidScheduleMode .inexactAllowWhileIdle, // évite l'erreur Exact Alarm uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.dateAndTime, ); } /// Annule une notification planifiée static Future cancel(String eventId) async { await _notificationsPlugin.cancel(eventId.hashCode); } }