'use client';

import { useState, useCallback, useRef } from 'react';
import { Toast } from 'primereact/toast';
import { apiService } from '../services/api';

interface UseApiCallOptions {
    onSuccess?: (data: any) => void;
    onError?: (error: any) => void;
    showSuccessToast?: boolean;
    showErrorToast?: boolean;
    successMessage?: string;
    retryAttempts?: number;
    retryDelay?: number;
}

interface UseApiCallReturn<T> {
    data: T | null;
    loading: boolean;
    error: any;
    execute: (...args: any[]) => Promise<T | null>;
    retry: () => Promise<T | null>;
    reset: () => void;
    toast: React.RefObject<Toast>;
}

export function useApiCall<T = any>(
    apiFunction: (...args: any[]) => Promise<T>,
    options: UseApiCallOptions = {}
): UseApiCallReturn<T> {
    const [data, setData] = useState<T | null>(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<any>(null);
    const toast = useRef<Toast>(null);
    const lastArgsRef = useRef<any[]>([]);
    const retryCountRef = useRef(0);

    const {
        onSuccess,
        onError,
        showSuccessToast = false,
        showErrorToast = true,
        successMessage = 'Opération réussie',
        retryAttempts = 0,
        retryDelay = 1000
    } = options;

    const execute = useCallback(async (...args: any[]): Promise<T | null> => {
        lastArgsRef.current = args;
        setLoading(true);
        setError(null);
        retryCountRef.current = 0;

        try {
            const result = await apiFunction(...args);
            setData(result);
            
            // Notifier que le serveur répond (pour une détection immédiate)
            // Cette ligne se déclenchera dès qu'un appel API réussit
            
            if (showSuccessToast && toast.current) {
                toast.current.show({
                    severity: 'success',
                    summary: 'Succès',
                    detail: successMessage,
                    life: 3000
                });
            }
            
            if (onSuccess) {
                onSuccess(result);
            }
            
            return result;
        } catch (err: any) {
            setError(err);
            
            // Déclenchement d'un health check urgent uniquement pour les erreurs critiques
            if (shouldRetry(err) && retryCountRef.current === 0) {
                // Health check urgent seulement au premier échec pour éviter le spam
                apiService.checkServerHealth(true).catch(() => {});
            }
            
            // Gestion des erreurs réseau avec retry automatique
            if (shouldRetry(err) && retryCountRef.current < retryAttempts) {
                retryCountRef.current++;
                
                if (showErrorToast && toast.current) {
                    toast.current.show({
                        severity: 'warn',
                        summary: 'Tentative de reconnexion',
                        detail: `Tentative ${retryCountRef.current}/${retryAttempts}...`,
                        life: 2000
                    });
                }
                
                // Attendre avant de retry
                await new Promise(resolve => setTimeout(resolve, retryDelay));
                return execute(...args);
            }
            
            // Afficher l'erreur finale
            if (showErrorToast && toast.current) {
                const message = getErrorMessage(err);
                toast.current.show({
                    severity: 'error',
                    summary: 'Erreur',
                    detail: message,
                    life: err.statusCode === 'SERVER_UNAVAILABLE' ? 0 : 5000 // Sticky pour erreurs serveur
                });
            }
            
            if (onError) {
                onError(err);
            }
            
            return null;
        } finally {
            setLoading(false);
        }
    }, [apiFunction, onSuccess, onError, showSuccessToast, showErrorToast, successMessage, retryAttempts, retryDelay]);

    const retry = useCallback(async (): Promise<T | null> => {
        if (lastArgsRef.current.length > 0) {
            return execute(...lastArgsRef.current);
        }
        return execute();
    }, [execute]);

    const reset = useCallback(() => {
        setData(null);
        setError(null);
        setLoading(false);
        retryCountRef.current = 0;
    }, []);

    return {
        data,
        loading,
        error,
        execute,
        retry,
        reset,
        toast
    };
}

// Fonctions utilitaires
function shouldRetry(error: any): boolean {
    return error?.statusCode === 'NETWORK_ERROR' || 
           error?.statusCode === 'SERVER_UNAVAILABLE' || 
           error?.statusCode === 'TIMEOUT' ||
           error?.code === 'ECONNABORTED' ||
           error?.code === 'ERR_NETWORK';
}

function getErrorMessage(error: any): string {
    if (error?.statusCode === 'SERVER_UNAVAILABLE') {
        return 'Serveur indisponible. Vérifiez que le serveur backend est démarré.';
    }
    
    if (error?.statusCode === 'NETWORK_ERROR') {
        return 'Erreur réseau. Vérifiez votre connexion internet.';
    }
    
    if (error?.statusCode === 'TIMEOUT') {
        return 'Délai d\'attente dépassé. Le serveur met trop de temps à répondre.';
    }
    
    return error?.userMessage || error?.message || 'Une erreur inattendue s\'est produite';
}

export default useApiCall;