/**
 * send-fcm
 *
 * Envoie des notifications FCM HTTP v1 à des tokens ou à un topic
 */

module.exports = {
    friendlyName: 'Envoyer notification FCM',

    inputs: {
        // Un de ces deux: tokens[] ou topic
        tokens: { type: 'ref', description: 'Tableau de tokens FCM' },
        topic: { type: 'string', description: 'Topic FCM' },
        title: { type: 'string', required: true },
        body: { type: 'string', required: true },
        data: { type: 'ref' }
    },

    exits: {
        success: { description: 'Notification envoyée' },
        error: { description: 'Erreur FCM' }
    },

    fn: async function (inputs, exits) {
        try {
            let projectId, clientEmail, privateKey;

            // Priorité 1: Essayer le fichier serviceAccountKey.json
            try {
                const fs = require('fs');
                const path = require('path');
                const serviceAccountPath = path.join(__dirname, '../../config/serviceAccountKey.json');

                if (fs.existsSync(serviceAccountPath)) {
                    const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountPath, 'utf8'));
                    projectId = serviceAccount.project_id;
                    clientEmail = serviceAccount.client_email;
                    privateKey = serviceAccount.private_key;
                    //console.log('🔐 Utilisation du fichier serviceAccountKey.json');
                } else {
                    throw new Error('Fichier serviceAccountKey.json non trouvé dans config/');
                }
            } catch (fileError) {
                //console.log('⚠️  Erreur lecture serviceAccountKey.json:', fileError.message);

                // Priorité 2: Fallback vers les variables d'environnement
                if (process.env.FIREBASE_PROJECT_ID && process.env.FIREBASE_CLIENT_EMAIL && process.env.FIREBASE_PRIVATE_KEY) {
                    projectId = process.env.FIREBASE_PROJECT_ID;
                    clientEmail = process.env.FIREBASE_CLIENT_EMAIL;
                    privateKey = process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n');
                    //console.log('🔐 Utilisation des variables d\'environnement Firebase');
                } else {
                    throw new Error('Configuration Firebase manquante. Fichier serviceAccountKey.json ou variables d\'environnement requis.');
                }
            }

            if (!projectId || !clientEmail || !privateKey) {
                throw new Error('Configuration Firebase incomplète');
            }

            //console.log('📋 Configuration Firebase chargée:');
            //console.log('- Project ID:', projectId);
            //console.log('- Client Email:', clientEmail);
            //console.log('- Private Key:', privateKey ? '✅ Présent' : '❌ Manquant');

            const { GoogleAuth } = require('google-auth-library');
            const auth = new GoogleAuth({
                credentials: { client_email: clientEmail, private_key: privateKey },
                scopes: ['https://www.googleapis.com/auth/firebase.messaging']
            });
            const client = await auth.getClient();
            const accessToken = await client.getAccessToken();

            const axios = require('axios');
            const url = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`;

            const makeMessage = (token) => ({
                message: {
                    token,
                    notification: { title: inputs.title, body: inputs.body },
                    data: inputs.data ? Object.fromEntries(Object.entries(inputs.data).map(([k, v]) => [k, typeof v === 'object' ? JSON.stringify(v) : String(v)])) : undefined
                }
            });

            const makeTopicMessage = (topic) => ({
                message: {
                    topic,
                    notification: { title: inputs.title, body: inputs.body },
                    data: inputs.data ? Object.fromEntries(Object.entries(inputs.data).map(([k, v]) => [k, typeof v === 'object' ? JSON.stringify(v) : String(v)])) : undefined
                }
            });

            const headers = { Authorization: `Bearer ${accessToken.token || accessToken}`, 'Content-Type': 'application/json; UTF-8' };

            if (inputs.topic) {
                const resp = await axios.post(url, makeTopicMessage(inputs.topic), { headers });
                return exits.success({ ok: true, type: 'topic', topic: inputs.topic, response: resp.data });
            }

            const tokens = Array.isArray(inputs.tokens) ? inputs.tokens : [];
            //console.log('📤 Envoi FCM pour', tokens.length, 'tokens');
            //console.log('🔗 URL FCM:', url);
            //console.log('🔑 Headers (sans token):', { ...headers, Authorization: 'Bearer ***' });

            const results = [];
            for (let i = 0; i < tokens.length; i++) {
                const token = tokens[i];
                //console.log(`📱 Envoi token ${i + 1}/${tokens.length}: ${token.substring(0, 20)}...`);

                try {
                    const message = makeMessage(token);
                    //console.log('📨 Message FCM:', JSON.stringify(message, null, 2));

                    const resp = await axios.post(url, message, { headers });
                    //console.log(`✅ Token ${i + 1} envoyé avec succès:`, resp.data);
                    results.push({ token, status: 'sent', id: resp.data?.name || null });
                } catch (e) {
                    const err = e.response?.data || e.message;
                    //console.error(`❌ Échec envoi token ${i + 1}:`, err);
                    /*console.error(`❌ Détails erreur:`, {
                        status: e.response?.status,
                        statusText: e.response?.statusText,
                        data: e.response?.data, 
                        message: e.message
                    });*/

                    results.push({ token, status: 'failed', error: err });

                    // Nettoyage: NotRegistered / InvalidRegistration
                    if (typeof err === 'string' && (/NotRegistered|InvalidRegistration/i).test(err)) {
                        //console.log(`🧹 Nettoyage token invalide: ${token.substring(0, 20)}...`);
                        try {
                            await PushToken.destroy({ fcmToken: token });
                            //console.log(`✅ Token nettoyé de la base`);
                        } catch (e2) {
                            console.error(`❌ Erreur nettoyage token:`, e2.message);
                        }
                    }
                }
            }

            return exits.success({ ok: true, type: 'tokens', count: results.length, results });
        } catch (e) {
            sails.log.error('FCM send error', e.response?.data || e.message || e);
            return exits.error(e);
        }
    }
};


