import 'dart:async'; import 'dart:io' show Platform; import 'package:firebase_messaging/firebase_messaging.dart'; import '../../../core/api/api_client.dart'; import '../../../core/di.dart'; import 'trip_event_merger.dart'; /// القناة الثانية للزمن الحقيقي — FCM data-message (docs/23 §15). /// /// للسائق: يستقبل عروض الرحلات (trip:offer) وتحديثات الحالة /// عبر FCM كطبقة احتياطية للسوكت. أيّهما يسبق يفوز — /// الـ merger يتكفّل بالتصفية الصامتة. class DriverFcmService { final DriverTripEventMerger _merger; StreamSubscription? _onMessageSub; StreamSubscription? _onOpenSub; DriverFcmService(this._merger); Future init() async { final messaging = FirebaseMessaging.instance; await messaging.requestPermission( alert: false, badge: false, sound: false, provisional: false, ); final token = await messaging.getToken(); if (token != null) { _registerToken(token); } messaging.onTokenRefresh.listen(_registerToken); _onMessageSub = FirebaseMessaging.onMessage.listen(_handleMessage); _onOpenSub = FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage); } void dispose() { _onMessageSub?.cancel(); _onOpenSub?.cancel(); } void _handleMessage(RemoteMessage message) { final data = message.data; final type = data['type'] as String?; final tripId = data['tripId'] as String?; if (type == null || tripId == null || tripId.isEmpty) return; switch (type) { case 'trip_offer': // عرض رحلة وارد — سيُعالج عبر OffersBloc. _merger.addNewTrip(tripId); break; case 'trip_offer_taken': // العرض تم قبوله من سائق آخر. _merger.addOfferTaken(tripId); break; default: // تحديث حالة رحلة نشطة. final status = type.startsWith('trip_') ? type.substring(5) : null; if (status == null) return; final extra = Map.from(data) ..remove('type') ..remove('tripId') ..remove('title') ..remove('body'); _merger.addUpdate(DriverTripUpdate( tripId: tripId, status: status, extra: extra, )); } } static Future _registerToken(String token) async { try { final api = getIt(); await api.dio.post('/notifications/token', data: { 'token': token, 'platform': Platform.isIOS ? 'ios' : 'android', }); } catch (_) {} } }