"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.recalculateTopPlayed = exports.updateTopPlayedOnHistoryChange = void 0;
const functions = require("firebase-functions");
const admin = require("firebase-admin");
// Initialize Firebase Admin
admin.initializeApp();
// Database reference
const db = admin.database();
/**
 * Cloud Function that triggers when a song is added to history
 * This function aggregates all history items to create/update the topPlayed collection
 * based on unique combinations of artist and title (not path)
 */
exports.updateTopPlayedOnHistoryChange = functions.database
    .ref('/controllers/{controllerName}/history/{historyId}')
    .onCreate(async (snapshot, context) => {
    const { controllerName } = context.params;
    console.log(`TopPlayed update triggered for controller: ${controllerName}`);
    try {
        // Get the controller reference
        const controllerRef = db.ref(`/controllers/${controllerName}`);
        // Get all history items for this controller
        const historySnapshot = await controllerRef.child('history').once('value');
        const historyData = historySnapshot.val();
        if (!historyData) {
            console.log('No history data found, skipping TopPlayed update');
            return;
        }
        // Aggregate history items by artist + title combination
        const aggregation = {};
        Object.values(historyData).forEach((song) => {
            const historySong = song;
            if (historySong && historySong.artist && historySong.title) {
                // Create a unique key based on artist and title (case-insensitive)
                // Replace invalid Firebase key characters with underscores
                const sanitizedArtist = historySong.artist.toLowerCase().trim().replace(/[.#$/[\]]/g, '_');
                const sanitizedTitle = historySong.title.toLowerCase().trim().replace(/[.#$/[\]]/g, '_');
                const key = `${sanitizedArtist}_${sanitizedTitle}`;
                if (aggregation[key]) {
                    // Increment count for existing song
                    aggregation[key].count += historySong.count || 1;
                }
                else {
                    // Create new entry
                    aggregation[key] = {
                        artist: historySong.artist,
                        title: historySong.title,
                        count: historySong.count || 1
                    };
                }
            }
        });
        // Convert aggregation to array, sort by count (descending), and take top 100
        const sortedSongs = Object.entries(aggregation)
            .map(([key, songData]) => ({
            key,
            artist: songData.artist,
            title: songData.title,
            count: songData.count
        }))
            .sort((a, b) => b.count - a.count) // Sort by count descending
            .slice(0, 100); // Take only top 100
        // Convert back to object format for Firebase
        const topPlayedData = {};
        sortedSongs.forEach((song) => {
            topPlayedData[song.key] = {
                artist: song.artist,
                title: song.title,
                count: song.count
            };
        });
        // Update the topPlayed collection
        await controllerRef.child('topPlayed').set(topPlayedData);
        console.log(`Successfully updated TopPlayed for controller ${controllerName} with ${Object.keys(topPlayedData).length} unique songs`);
    }
    catch (error) {
        console.error('Error updating TopPlayed:', error);
        throw error;
    }
});
/**
 * Alternative function that can be called manually to recalculate TopPlayed
 * This is useful for initial setup or data migration
 */
exports.recalculateTopPlayed = functions.https.onCall(async (data, context) => {
    const { controllerName } = data;
    if (!controllerName) {
        throw new functions.https.HttpsError('invalid-argument', 'controllerName is required');
    }
    console.log(`Manual TopPlayed recalculation requested for controller: ${controllerName}`);
    try {
        // Get the controller reference
        const controllerRef = db.ref(`/controllers/${controllerName}`);
        // Get all history items for this controller
        const historySnapshot = await controllerRef.child('history').once('value');
        const historyData = historySnapshot.val();
        if (!historyData) {
            console.log('No history data found, returning empty TopPlayed');
            await controllerRef.child('topPlayed').set({});
            return { success: true, message: 'No history data found, TopPlayed cleared' };
        }
        // Aggregate history items by artist + title combination
        const aggregation = {};
        Object.values(historyData).forEach((song) => {
            const historySong = song;
            if (historySong && historySong.artist && historySong.title) {
                // Create a unique key based on artist and title (case-insensitive)
                // Replace invalid Firebase key characters with underscores
                const sanitizedArtist = historySong.artist.toLowerCase().trim().replace(/[.#$/[\]]/g, '_');
                const sanitizedTitle = historySong.title.toLowerCase().trim().replace(/[.#$/[\]]/g, '_');
                const key = `${sanitizedArtist}_${sanitizedTitle}`;
                if (aggregation[key]) {
                    // Increment count for existing song
                    aggregation[key].count += historySong.count || 1;
                }
                else {
                    // Create new entry
                    aggregation[key] = {
                        artist: historySong.artist,
                        title: historySong.title,
                        count: historySong.count || 1
                    };
                }
            }
        });
        // Convert aggregation to array, sort by count (descending), and take top 100
        const sortedSongs = Object.entries(aggregation)
            .map(([key, songData]) => ({
            key,
            artist: songData.artist,
            title: songData.title,
            count: songData.count
        }))
            .sort((a, b) => b.count - a.count) // Sort by count descending
            .slice(0, 100); // Take only top 100
        // Convert back to object format for Firebase
        const topPlayedData = {};
        sortedSongs.forEach((song) => {
            topPlayedData[song.key] = {
                artist: song.artist,
                title: song.title,
                count: song.count
            };
        });
        // Update the topPlayed collection
        await controllerRef.child('topPlayed').set(topPlayedData);
        console.log(`Successfully recalculated TopPlayed for controller ${controllerName} with ${Object.keys(topPlayedData).length} unique songs`);
        return {
            success: true,
            message: `TopPlayed recalculated successfully`,
            songCount: Object.keys(topPlayedData).length
        };
    }
    catch (error) {
        console.error('Error recalculating TopPlayed:', error);
        throw new functions.https.HttpsError('internal', 'Failed to recalculate TopPlayed');
    }
});
//# sourceMappingURL=index.js.map