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<WavePaymentResult>;
  checkTransactionStatus: (transactionId: string) => Promise<WaveTransactionStatus>;
  refreshTransactions: () => Promise<void>;
  syncPendingPayments: () => Promise<void>;
  clearCurrentTransaction: () => void;
  
  // Utilitaires
  calculateFees: (amount: string) => Promise<{ base: string; fees: string; total: string }>;
  getPaymentHistory: () => Promise<WavePaymentResult[]>;
}

const WavePaymentContext = createContext<WavePaymentContextType | undefined>(undefined);

interface WavePaymentProviderProps {
  children: ReactNode;
}

export const WavePaymentProvider: React.FC<WavePaymentProviderProps> = ({ children }) => {
  const [isLoading, setIsLoading] = useState(false);
  const [currentTransaction, setCurrentTransaction] = useState<WavePaymentResult | null>(null);
  const [recentTransactions, setRecentTransactions] = useState<WavePaymentResult[]>([]);
  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<WavePaymentResult> => {
    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<WaveTransactionStatus> => {
    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<WavePaymentResult[]> => {
    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 (
    <WavePaymentContext.Provider value={contextValue}>
      {children}
    </WavePaymentContext.Provider>
  );
};

/**
 * 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,
  };
};
