import * as Notifications from 'expo-notifications'; import * as Device from 'expo-device'; import * as Constants from 'expo-constants'; import { Platform } from 'react-native'; import api from './api'; Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowBanner: true, shouldShowList: true, shouldPlaySound: true, shouldSetBadge: true, }), }); let _cachedToken: string | null = null; export async function registerForPushNotifications() { if (!Device.isDevice) { console.log('Push notifications require a physical device'); return null; } const { status: existingStatus } = await Notifications.getPermissionsAsync(); let finalStatus = existingStatus; if (existingStatus !== 'granted') { const { status } = await Notifications.requestPermissionsAsync(); finalStatus = status; } if (finalStatus !== 'granted') { console.log('Failed to get push token for push notification'); return null; } if (Platform.OS === 'android') { await Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#007AFF', }); } try { const projectId = Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId; const token = await Notifications.getExpoPushTokenAsync({ projectId, }); _cachedToken = token.data; // Register token with backend (fire and forget) registerTokenWithBackend(token.data).catch(() => {}); return token.data; } catch (e) { console.log('Error getting push token:', e); return null; } } async function registerTokenWithBackend(token: string) { try { await api.post('/notifications/expo-register', { token }); } catch (e) { console.log('Failed to register push token with backend:', e); } } export async function subscribeToMedicine( medicineNregistro: string, medicineName: string | null, pharmacyId?: number | null ) { const token = _cachedToken; if (!token) { console.log('No push token available for subscription'); return; } try { await api.post('/notifications/expo-register', { token, medicine_nregistro: medicineNregistro, medicine_name: medicineName, pharmacy_id: pharmacyId || null, }); } catch (e) { console.log('Failed to subscribe to medicine notifications:', e); } } export async function unsubscribeFromMedicine( medicineNregistro: string, pharmacyId?: number | null ) { try { await api.delete('/notifications/expo-unregister', { data: { medicine_nregistro: medicineNregistro, pharmacy_id: pharmacyId || null, }, }); } catch (e) { console.log('Failed to unsubscribe from medicine notifications:', e); } } export async function scheduleMedicineAvailabilityNotification( medicineName: string, pharmacyName: string ) { await Notifications.scheduleNotificationAsync({ content: { title: 'Medicamento disponible', body: `${medicineName} está disponible en ${pharmacyName}`, data: { type: 'medicine_availability' }, }, trigger: null, }); } export function addNotificationListener( handler: (notification: Notifications.Notification) => void ): Notifications.EventSubscription { return Notifications.addNotificationReceivedListener(handler); } export function addNotificationResponseListener( handler: (response: Notifications.NotificationResponse) => void ): Notifications.EventSubscription { return Notifications.addNotificationResponseReceivedListener(handler); }