const functions = require("firebase-functions/v1");
const admin = require("firebase-admin");

admin.initializeApp();

// Helper function to send notifications to a list of users
async function sendNotificationToUsers(userIds, title, body, excludeUserId, data = {}) {
    console.log(`Starting sendNotificationToUsers. Total users: ${userIds.length}, Exclude: ${excludeUserId}`);
    try {
        const tokens = [];

        for (const userId of userIds) {
            if (userId === excludeUserId) {
                console.log(`Skipping user ${userId} (sender)`);
                continue;
            }

            const userDoc = await admin.firestore().collection("users").doc(userId).get();
            if (userDoc.exists) {
                const userData = userDoc.data();
                if (userData.fcmToken) {
                    console.log(`Found token for user ${userId}`);
                    tokens.push(userData.fcmToken);
                } else {
                    console.log(`No FCM token found for user ${userId}`);
                }
            } else {
                console.log(`User document not found for ${userId}`);
            }
        }

        // De-duplicate tokens
        const uniqueTokens = [...new Set(tokens)];
        console.log(`Total unique tokens to send: ${uniqueTokens.length} (from ${tokens.length} found)`);

        if (uniqueTokens.length > 0) {
            const message = {
                notification: {
                    title: title,
                    body: body,
                },
                tokens: uniqueTokens,
                data: {
                    click_action: "FLUTTER_NOTIFICATION_CLICK",
                    ...data
                },
                android: {
                    priority: "high",
                    notification: {
                        channelId: "high_importance_channel",
                    }
                }
            };

            const response = await admin.messaging().sendEachForMulticast(message);
            console.log(`${response.successCount} messages were sent successfully`);
            if (response.failureCount > 0) {
                console.log('Failed notifications:', response.responses.filter(r => !r.success));
            }
        } else {
            console.log("No tokens found, skipping notification send.");
        }
    } catch (error) {
        console.error("Error sending notification:", error);
    }
}

exports.onActivityCreated = functions.firestore
    .document("activities/{activityId}")
    .onCreate(async (snapshot, context) => {
        console.log(`onActivityCreated triggered for ${context.params.activityId}`);
        const activity = snapshot.data();
        const tripId = activity.tripId;
        const createdBy = activity.createdBy || "Unknown";

        if (!tripId) {
            console.log("No tripId found in activity");
            return;
        }

        // Fetch trip to get participants
        const tripDoc = await admin.firestore().collection("trips").doc(tripId).get();
        if (!tripDoc.exists) {
            console.log(`Trip ${tripId} not found`);
            return;
        }

        const trip = tripDoc.data();
        const participants = trip.participants || [];
        if (trip.createdBy && !participants.includes(trip.createdBy)) {
            participants.push(trip.createdBy);
        }

        console.log(`Found trip participants: ${JSON.stringify(participants)}`);

        // Fetch creator name
        let creatorName = "Quelqu'un";
        if (createdBy !== "Unknown") {
            const userDoc = await admin.firestore().collection("users").doc(createdBy).get();
            if (userDoc.exists) {
                creatorName = userDoc.data().prenom || "Quelqu'un";
            }
        }

        await sendNotificationToUsers(
            participants,
            "Nouvelle activité !",
            `${creatorName} a ajouté une nouvelle activité : ${activity.name || activity.title}`,
            createdBy,
            { tripId: tripId }
        );
    });

exports.onMessageCreated = functions.firestore
    .document("groups/{groupId}/messages/{messageId}")
    .onCreate(async (snapshot, context) => {
        console.log(`onMessageCreated triggered for ${context.params.messageId} in group ${context.params.groupId}`);
        const message = snapshot.data();
        const groupId = context.params.groupId;
        const senderId = message.senderId;

        // Fetch group to get members
        const groupDoc = await admin.firestore().collection("groups").doc(groupId).get();
        if (!groupDoc.exists) {
            console.log(`Group ${groupId} not found`);
            return;
        }

        const group = groupDoc.data();
        const memberIds = group.memberIds || [];
        console.log(`Found group members: ${JSON.stringify(memberIds)}`);

        let senderName = message.senderName || "Quelqu'un";

        await sendNotificationToUsers(
            memberIds,
            "Nouveau message",
            `${senderName} : ${message.text}`,
            senderId,
            { groupId: groupId }
        );
    });

exports.onExpenseCreated = functions.firestore
    .document("expenses/{expenseId}")
    .onCreate(async (snapshot, context) => {
        console.log(`onExpenseCreated triggered for ${context.params.expenseId}`);
        const expense = snapshot.data();
        const groupId = expense.groupId;
        const paidBy = expense.paidById || expense.paidBy;

        if (!groupId) {
            console.log("No groupId found in expense");
            return;
        }

        // Fetch group to get members
        const groupDoc = await admin.firestore().collection("groups").doc(groupId).get();
        if (!groupDoc.exists) {
            console.log(`Group ${groupId} not found`);
            return;
        }

        const group = groupDoc.data();
        const memberIds = group.memberIds || [];
        console.log(`Found group members: ${JSON.stringify(memberIds)}`);

        let payerName = expense.paidByName || "Quelqu'un";

        await sendNotificationToUsers(
            memberIds,
            "Nouvelle dépense",
            `${payerName} a ajouté une dépense : ${expense.amount} ${expense.currency || '€'}`,
            paidBy,
            { groupId: groupId }
        );
    });

exports.callbacks_signInWithApple = functions.https.onRequest((req, res) => {
    const code = req.body.code;
    const state = req.body.state;
    const id_token = req.body.id_token;
    const user = req.body.user;

    const params = new URLSearchParams();
    if (code) params.append('code', code);
    if (state) params.append('state', state);
    if (id_token) params.append('id_token', id_token);
    if (user) params.append('user', user);

    const qs = params.toString();
    const packageName = 'be.devdayronvl.travel_mate';
    const redirectUrl = `intent://callback?${qs}#Intent;package=${packageName};scheme=signinwithapple;end`;

    res.redirect(302, redirectUrl);
});
