import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; import NetInfo from '@react-native-community/netinfo'; import { WavePaymentService, WavePaymentRequest, WavePaymentResult, WaveTransactionStatus } from '../services/WavePaymentService'; import { AnalyticsService } from '../services/AnalyticsService'; /** * Contexte Wave Payment pour la gestion globale des paiements Wave Money * * Ce contexte fournit : * - État global des paiements Wave * - Gestion de la connectivité et synchronisation * - Cache des transactions récentes * - Notifications de statut en temps réel * * @author Lions Dev Team * @version 2.0.0 * @since 2025-01-16 */ interface WavePaymentContextType { // État des paiements isLoading: boolean; currentTransaction: WavePaymentResult | null; recentTransactions: WavePaymentResult[]; // Connectivité isOnline: boolean; pendingPaymentsCount: number; // Actions initiatePayment: (request: WavePaymentRequest) => Promise; checkTransactionStatus: (transactionId: string) => Promise; refreshTransactions: () => Promise; syncPendingPayments: () => Promise; clearCurrentTransaction: () => void; // Utilitaires calculateFees: (amount: string) => Promise<{ base: string; fees: string; total: string }>; getPaymentHistory: () => Promise; } const WavePaymentContext = createContext(undefined); interface WavePaymentProviderProps { children: ReactNode; } export const WavePaymentProvider: React.FC = ({ children }) => { const [isLoading, setIsLoading] = useState(false); const [currentTransaction, setCurrentTransaction] = useState(null); const [recentTransactions, setRecentTransactions] = useState([]); const [isOnline, setIsOnline] = useState(true); const [pendingPaymentsCount, setPendingPaymentsCount] = useState(0); useEffect(() => { initializeContext(); setupNetworkListener(); }, []); /** * Initialise le contexte avec les données sauvegardées */ const initializeContext = async () => { try { // Charger l'historique des paiements const history = await WavePaymentService.getPaymentHistory(); setRecentTransactions(history.slice(0, 10)); // 10 plus récents // Compter les paiements en attente await updatePendingPaymentsCount(); } catch (error) { console.error('Erreur initialisation contexte Wave:', error); } }; /** * Configure l'écoute de la connectivité réseau */ const setupNetworkListener = () => { const unsubscribe = NetInfo.addEventListener(state => { const wasOffline = !isOnline; const isNowOnline = state.isConnected ?? false; setIsOnline(isNowOnline); // Si on revient en ligne, synchroniser les paiements en attente if (wasOffline && isNowOnline) { console.log('Connexion rétablie - Synchronisation des paiements Wave'); syncPendingPayments(); } }); return unsubscribe; }; /** * Met à jour le nombre de paiements en attente */ const updatePendingPaymentsCount = async () => { try { const pendingPayments = await WavePaymentService.getPendingPayments(); setPendingPaymentsCount(pendingPayments.length); } catch (error) { console.error('Erreur mise à jour paiements en attente:', error); } }; /** * Initie un paiement Wave Money */ const initiatePayment = async (request: WavePaymentRequest): Promise => { setIsLoading(true); setCurrentTransaction(null); try { const result = await WavePaymentService.initiatePayment(request); setCurrentTransaction(result); if (result.success) { // Ajouter à l'historique récent setRecentTransactions(prev => [result, ...prev.slice(0, 9)]); // Analytics AnalyticsService.trackEvent('wave_payment_context_success', { type: request.type, amount: request.amount, transactionId: result.transactionId, }); } else { // Si échec à cause de la connectivité, mettre à jour le compteur if (!isOnline) { await updatePendingPaymentsCount(); } AnalyticsService.trackEvent('wave_payment_context_failure', { type: request.type, amount: request.amount, error: result.error, }); } return result; } catch (error) { console.error('Erreur contexte paiement Wave:', error); const errorResult: WavePaymentResult = { success: false, error: 'Erreur inattendue lors du paiement', }; setCurrentTransaction(errorResult); return errorResult; } finally { setIsLoading(false); } }; /** * Vérifie le statut d'une transaction */ const checkTransactionStatus = async (transactionId: string): Promise => { try { const status = await WavePaymentService.checkTransactionStatus(transactionId); // Mettre à jour la transaction dans l'historique si nécessaire setRecentTransactions(prev => prev.map(transaction => transaction.transactionId === transactionId ? { ...transaction, status: status.status as any } : transaction ) ); return status; } catch (error) { console.error('Erreur vérification statut:', error); throw error; } }; /** * Actualise la liste des transactions */ const refreshTransactions = async () => { try { const history = await WavePaymentService.getPaymentHistory(); setRecentTransactions(history.slice(0, 10)); await updatePendingPaymentsCount(); } catch (error) { console.error('Erreur actualisation transactions:', error); } }; /** * Synchronise les paiements en attente */ const syncPendingPayments = async () => { if (!isOnline) { console.log('Hors ligne - Synchronisation reportée'); return; } try { await WavePaymentService.syncPendingPayments(); await updatePendingPaymentsCount(); await refreshTransactions(); AnalyticsService.trackEvent('wave_payments_synced', { pendingCount: pendingPaymentsCount, }); } catch (error) { console.error('Erreur synchronisation paiements:', error); } }; /** * Efface la transaction courante */ const clearCurrentTransaction = () => { setCurrentTransaction(null); }; /** * Calcule les frais Wave Money */ const calculateFees = async (amount: string) => { try { return await WavePaymentService.calculateFees(amount); } catch (error) { console.error('Erreur calcul frais contexte:', error); throw error; } }; /** * Retourne l'historique complet des paiements */ const getPaymentHistory = async (): Promise => { try { return await WavePaymentService.getPaymentHistory(); } catch (error) { console.error('Erreur récupération historique:', error); return []; } }; const contextValue: WavePaymentContextType = { // État isLoading, currentTransaction, recentTransactions, isOnline, pendingPaymentsCount, // Actions initiatePayment, checkTransactionStatus, refreshTransactions, syncPendingPayments, clearCurrentTransaction, // Utilitaires calculateFees, getPaymentHistory, }; return ( {children} ); }; /** * Hook pour utiliser le contexte Wave Payment */ export const useWavePayment = (): WavePaymentContextType => { const context = useContext(WavePaymentContext); if (context === undefined) { throw new Error('useWavePayment doit être utilisé dans un WavePaymentProvider'); } return context; }; /** * Hook pour vérifier si Wave Money est disponible */ export const useWaveAvailability = () => { const { isOnline } = useWavePayment(); return { isWaveAvailable: isOnline, // Simplification - en réalité, vérifier aussi la config reason: isOnline ? null : 'Connexion internet requise', }; }; /** * Hook pour les statistiques de paiement Wave */ export const useWaveStats = () => { const { recentTransactions, pendingPaymentsCount } = useWavePayment(); const successfulPayments = recentTransactions.filter(t => t.success).length; const failedPayments = recentTransactions.filter(t => !t.success).length; const totalAmount = recentTransactions .filter(t => t.success) .reduce((sum, t) => { // Extraire le montant de la transaction (simplification) return sum + 0; // À implémenter selon le format des données }, 0); return { successfulPayments, failedPayments, pendingPaymentsCount, totalAmount, successRate: recentTransactions.length > 0 ? (successfulPayments / recentTransactions.length) * 100 : 0, }; };