import { redisClient } from './redis.js';
import { logger } from './logger.js';

const getLikesKey = (id) => `structure:likes:${id}`;

/**
 * This function publishes the number of likes for a given structure ID
 * to a Redis channel.
 * @param {string} id - The ID of the structure for which likes are being published.
 * @param {number} likes - The number of likes to publish.
 * @returns {void}
 */
export function publishLikes(id, likes) {
    redisClient.publish(getLikesKey(id), likes.toString());
}

/**
 * This function initializes the online user count feature by setting up an endpoint
 * that serves the current count of online users. The count is updated in real-time
 * using Server-Sent Events (SSE) and Redis pub/sub.
 * 
 * @param {express.Express} app - The Express application instance.
 * @returns {void}
 */
export function initSubscribeStructureLikes(app) {
    app.get('/api/subscribe-likes', async (req, res) => {
        res.writeHead(200, {
            "Connection": "keep-alive",
            "Cache-Control": "no-cache",
            "Content-Type": "text/event-stream",
        });

        logger.info('New SSE connection established');

        // Periodically refresh the expiration time (heartbeat)
        const pingInterval = setInterval(async () => {
            res.write(`event: heartbeat\n`);
            res.write(`data: ${new Date().toISOString()}\n\n`);
        }, 1000);

        // Subscribe to Redis pub/sub for updates (optional)
        const subscriber = redisClient.duplicate();
        await subscriber.connect();
        await subscriber.pSubscribe('structure:likes:*', async (message, channel) => {
            // Extract the structure ID from the channel name
            const structureId = channel.split(':')[2];

            // Create a message to send
            message = JSON.stringify({
                structureId,
                likes: parseInt(message, 10)
            });

            res.write(`data: ${message}\n\n`);
        });

        res.on('close', async () => {
            logger.info('SSE connection closed');
            clearInterval(pingInterval);
            await subscriber.disconnect();
        });
    });
}

