// webhook-utils.js (VERSION ES MODULES - CORRIGÉE)
// Pour projets avec "type": "module" dans package.json

import axios from 'axios';
import crypto from 'crypto';

class WebhookManager {
    constructor(secretKey) {
        this.secretKey = secretKey;
    }

    /**
     * Génère une signature HMAC SHA-256 pour sécuriser le webhook
     * @param {Object} payload - Les données à signer
     * @returns {string} La signature hexadécimale
     */
    generateSignature(payload) {
        return crypto
            .createHmac('sha256', this.secretKey)
            .update(JSON.stringify(payload))
            .digest('hex');
    }

    /**
     * Vérifie la signature d'un webhook reçu
     * @param {Object} payload - Les données reçues
     * @param {string} receivedSignature - La signature reçue dans le header
     * @returns {boolean} True si la signature est valide
     */
    verifySignature(payload, receivedSignature) {
        if (!receivedSignature) {
            console.error('❌ Aucune signature fournie');
            return false;
        }

        try {
            const expectedSignature = this.generateSignature(payload);
            return crypto.timingSafeEqual(
                Buffer.from(expectedSignature),
                Buffer.from(receivedSignature)
            );
        } catch (error) {
            console.error('❌ Erreur vérification signature:', error);
            return false;
        }
    }

    /**
     * Envoie un webhook à une URL cible avec retry automatique
     * @param {string} targetUrl - URL du serveur cible
     * @param {string} eventType - Type d'événement (ex: 'demande.validated')
     * @param {Object} data - Données de l'événement
     * @param {number} retries - Nombre de tentatives (défaut: 3)
     * @returns {Promise<Object>} La réponse du serveur
     */
    async sendWebhook(targetUrl, eventType, data, retries = 3) {
        const payload = {
            event: eventType,
            data: data,
            timestamp: new Date().toISOString()
        };

        const signature = this.generateSignature(payload);

        for (let attempt = 1; attempt <= retries; attempt++) {
            try {
                console.log(`📤 Envoi webhook: ${eventType} vers ${targetUrl} (tentative ${attempt}/${retries})`);
                console.log(`   Données:`, JSON.stringify(data, null, 2));

                const response = await axios.post(
                    `${targetUrl}/api/webhook/receive`,
                    payload,
                    {
                        headers: {
                            'Content-Type': 'application/json',
                            'X-Webhook-Signature': signature
                        },
                        timeout: 5000 // 5 secondes de timeout
                    }
                );

                console.log(`✅ Webhook envoyé avec succès: ${eventType}`);
                return response.data;

            } catch (error) {
                console.error(`❌ Erreur envoi webhook (tentative ${attempt}/${retries}):`, error.message);

                if (attempt === retries) {
                    console.error(`❌ Échec définitif du webhook après ${retries} tentatives`);
                    throw error;
                }

                // Attendre avant de réessayer (backoff exponentiel)
                const waitTime = 1000 * attempt;
                console.log(`⏳ Nouvelle tentative dans ${waitTime}ms...`);
                await new Promise(resolve => setTimeout(resolve, waitTime));
            }
        }
    }

    /**
     * Envoie un webhook sans attendre la réponse (fire and forget)
     * Utile pour ne pas bloquer l'exécution
     * @param {string} targetUrl - URL du serveur cible
     * @param {string} eventType - Type d'événement
     * @param {Object} data - Données de l'événement
     */
    sendWebhookAsync(targetUrl, eventType, data) {
        this.sendWebhook(targetUrl, eventType, data)
            .catch(error => {
                console.error('❌ Webhook async échoué (non bloquant):', error.message);
            });
    }
}

export default WebhookManager;