make the analytics advanced include all type of data anlytics like graph table pir and everyttpe to cover all data analytic need and indepth filter for everything like make it super awsome and good include everything make it best and perfect and extensive 
""""
const { z } = require('zod');
const mongoose = require('mongoose');
const User = require('../models/User');
const Log = require('../models/Log');
const monitorService = require('../services/monitorService');
const logger = require('../utils/logger');

/**
 * Zod Schemas for Validation
 */

// Schema for updating user settings
const updateSettingsSchema = z.object({
    listOfUrls: z.array(z.string().url()).optional(),
    timePeriod: z.enum(['30s', '1m', '3m', '5m', '10m', '1h']).optional(),
    emailSend: z.boolean().optional(),
});

// Schema for getting user logs (pagination)
const getLogsQuerySchema = z.object({
    page: z
        .string()
        .optional()
        .refine((val) => !val || /^\d+$/.test(val), {
            message: 'page must be a positive integer',
        })
        .default('1'),
    limit: z
        .string()
        .optional()
        .refine((val) => !val || (/^\d+$/.test(val) && parseInt(val) <= 1000), {
            message: 'limit must be a positive integer not exceeding 1000',
        })
        .default('20'),
});

// Schema for analytics
const analyticsSchema = z.object({
    startDate: z
        .string()
        .optional()
        .refine((date) => !date || !isNaN(Date.parse(date)), {
            message: 'startDate must be a valid ISO date string',
        }),
    endDate: z
        .string()
        .optional()
        .refine((date) => !date || !isNaN(Date.parse(date)), {
            message: 'endDate must be a valid ISO date string',
        }),
    urls: z
        .string()
        .optional()
        .refine(
            (urls) => {
                if (!urls) return true;
                const urlsArray = urls.split(',');
                return urlsArray.every((url) => {
                    try {
                        new URL(url.trim());
                        return true;
                    } catch {
                        return false;
                    }
                });
            },
            { message: 'urls must be a comma-separated list of valid URLs' }
        ),
    statusCodes: z
        .string()
        .optional()
        .refine(
            (codes) => {
                if (!codes) return true;
                const codesArray = codes.split(',');
                return codesArray.every((code) => /^\d+$/.test(code.trim()));
            },
            { message: 'statusCodes must be a comma-separated list of numbers' }
        ),
    groupBy: z
        .enum(['day', 'week', 'month'])
        .optional()
        .default('day'),
    page: z
        .string()
        .optional()
        .refine((val) => !val || /^\d+$/.test(val), {
            message: 'page must be a positive integer',
        })
        .default('1'),
    limit: z
        .string()
        .optional()
        .refine((val) => !val || (/^\d+$/.test(val) && parseInt(val) <= 1000), {
            message: 'limit must be an integer between 1 and 1000',
        })
        .default('100'),
});

/**
 * Controller Methods
 */

/**
 * Update User Settings
 * PATCH /api/user/settings
 */
exports.updateSettings = async (req, res) => {
    try {
        // Validate input
        const parsedData = updateSettingsSchema.parse(req.body);

        // Update user
        const updatedUser = await User.findByIdAndUpdate(
            req.user.id,
            { $set: parsedData },
            { new: true, runValidators: true, context: 'query' }
        );

        if (!updatedUser) return res.status(404).json({ message: 'User not found' });

        // **Check if user is verified before restarting monitoring**
        if (updatedUser.verified) {
            try {
                monitorService.restartMonitoring(updatedUser);
            } catch (monitorError) {
                // Handle monitoring errors, possibly due to unverified status
                logger.error('Restart Monitoring Error:', monitorError);
                return res.status(400).json({ message: monitorError.message });
            }
        } else {
            logger.warn(`User ${updatedUser.username} is not verified. Monitoring not started.`);
            return res.status(403).json({ message: 'Email not verified. Please verify your email to start monitoring.' });
        }

        res.status(200).json({ message: 'Settings updated successfully', user: updatedUser });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({ errors: error.errors });
        }
        // Handle duplicate key error (e.g., email or username already exists)
        if (error.code === 11000) {
            const field = Object.keys(error.keyValue)[0];
            return res.status(400).json({ message: `${field.charAt(0).toUpperCase() + field.slice(1)} already exists` });
        }
        logger.error('Update Settings Error:', error);
        res.status(500).json({ message: 'Server Error' });
    }
};

/**
 * Get User Logs
 * GET /api/user/logs
 */
exports.getUserLogs = async (req, res) => {
    try {
        // Validate query parameters
        const parsedQuery = getLogsQuerySchema.parse(req.query);
        const page = parseInt(parsedQuery.page);
        const limit = parseInt(parsedQuery.limit);
        const skip = (page - 1) * limit;

        // Fetch logs from the database, sorted by most recent
        const logs = await Log.find({ user: req.user.id })
                              .sort({ checkedAt: -1 })
                              .limit(limit)
                              .skip(skip)
                              .exec();

        // Get total count for pagination
        const totalLogs = await Log.countDocuments({ user: req.user.id });

        res.status(200).json({
            totalPages: Math.ceil(totalLogs / limit),
            currentPage: page,
            logs,
        });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({ errors: error.errors });
        }
        logger.error('Get User Logs Error:', error);
        res.status(500).json({ message: 'Server Error' });
    }
};

/**
 * Start Monitoring
 * POST /api/user/monitor/start
 */
exports.startMonitoring = async (req, res) => {
    try {
        const user = await User.findById(req.user.id);

        if (!user) {
            return res.status(404).json({ message: 'User not found' });
        }

        if (!user.verified) {
            return res.status(403).json({ message: 'Email not verified. Please verify your email to start monitoring.' });
        }

        if (!user.listOfUrls || user.listOfUrls.length === 0) {
            return res.status(400).json({ message: 'No URLs configured for monitoring. Please add URLs to your settings.' });
        }

        // Check if monitoring is already active
        const isMonitoringActive = monitorService.isMonitoringActive(user._id.toString());
        if (isMonitoringActive) {
            return res.status(400).json({ message: 'Monitoring is already active for your account.' });
        }

        // Start monitoring
        monitorService.startMonitoring(user);

        res.status(200).json({ message: 'Monitoring started successfully.' });
    } catch (error) {
        logger.error('Start Monitoring Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

/**
 * Stop Monitoring
 * POST /api/user/monitor/stop
 */
exports.stopMonitoring = async (req, res) => {
    try {
        const user = await User.findById(req.user.id);

        if (!user) {
            return res.status(404).json({ message: 'User not found' });
        }

        // Check if monitoring is active
        const isMonitoringActive = monitorService.isMonitoringActive(user._id.toString());
        if (!isMonitoringActive) {
            return res.status(400).json({ message: 'Monitoring is not active for your account.' });
        }

        // Stop monitoring
        monitorService.stopMonitoring(user);

        res.status(200).json({ message: 'Monitoring stopped successfully.' });
    } catch (error) {
        logger.error('Stop Monitoring Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

/**
 * Get Analytics
 * GET /api/user/analytics
 */
exports.getAnalytics = async (req, res) => {
    try {
        const userId = req.user.id;

        // Validate and parse query parameters
        const parsed = analyticsSchema.parse(req.query);
        const { startDate, endDate, urls, statusCodes, groupBy, page, limit } = parsed;

        // Build the match criteria for MongoDB aggregation
        const matchCriteria = { user: new mongoose.Types.ObjectId(userId) };

        if (startDate || endDate) {
            matchCriteria.checkedAt = {};
            if (startDate) {
                matchCriteria.checkedAt.$gte = new Date(startDate);
            }
            if (endDate) {
                matchCriteria.checkedAt.$lte = new Date(endDate);
            }
        }

        if (urls) {
            const urlsArray = urls.split(',').map(url => url.trim());
            matchCriteria.url = { $in: urlsArray };
        }

        if (statusCodes) {
            const statusCodesArray = statusCodes.split(',').map(code => parseInt(code.trim()));
            matchCriteria.statusCode = { $in: statusCodesArray };
        }

        /**
         * Aggregation Pipelines
         */

        // Total Checks
        const totalChecksPromise = Log.countDocuments(matchCriteria).exec();

        // Successful Checks (2xx)
        const successfulChecksPromise = Log.countDocuments({
            ...matchCriteria,
            statusCode: { $gte: 200, $lt: 300 },
        }).exec();

        // Failed Checks (non-2xx)
        const failedChecksPromise = Log.countDocuments({
            ...matchCriteria,
            statusCode: { $gte: 400 }, // Considering 4xx and 5xx as failures
        }).exec();

        // Status Code Distribution
        const statusCodeDistributionPromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $group: {
                    _id: '$statusCode',
                    count: { $sum: 1 },
                },
            },
            { $sort: { count: -1 } },
        ]).exec();

        // Uptime Percentage per URL
        const uptimePerUrlPromise = Log.aggregate([
            { $match: { ...matchCriteria, statusCode: { $gte: 200, $lt: 300 } } },
            {
                $group: {
                    _id: '$url',
                    successCount: { $sum: 1 },
                },
            },
            {
                $lookup: {
                    from: 'logs',
                    let: { url: '$_id' },
                    pipeline: [
                        { $match: { 
                            $expr: { $eq: ['$url', '$$url'] },
                            ...(startDate || endDate ? {
                                ...(startDate ? { $gte: ['$checkedAt', new Date(startDate)] } : {}),
                                ...(endDate ? { $lte: ['$checkedAt', new Date(endDate)] } : {}),
                            } : {})
                        } },
                        { $count: 'totalCount' },
                    ],
                    as: 'total',
                },
            },
            {
                $addFields: {
                    totalCount: { $arrayElemAt: ['$total.totalCount', 0] },
                },
            },
            {
                $project: {
                    _id: 1,
                    successCount: 1,
                    totalCount: { $ifNull: ['$totalCount', 0] },
                    uptimePercentage: {
                        $cond: [
                            { $eq: ['$totalCount', 0] },
                            0,
                            { $multiply: [{ $divide: ['$successCount', '$totalCount'] }, 100] },
                        ],
                    },
                },
            },
        ]).exec();

        // Checks Over Time
        const checksOverTimePromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $group: {
                    _id: {
                        year: { $year: '$checkedAt' },
                        month: { $month: '$checkedAt' },
                        week: { $week: '$checkedAt' },
                        day: { $dayOfMonth: '$checkedAt' },
                    },
                    count: { $sum: 1 },
                },
            },
            {
                $project: {
                    _id: 0,
                    period: getPeriodExpression(groupBy),
                    count: 1,
                },
            },
            {
                $group: {
                    _id: '$period',
                    total: { $sum: '$count' },
                },
            },
            { $sort: { '_id': 1 } },
        ]).exec();

        // Recent Issues
        const recentIssuesPromise = Log.find({
            ...matchCriteria,
            statusCode: { $gte: 400 }, // Client and Server errors
        })
            .sort({ checkedAt: -1 })
            .limit(10)
            .select('url statusCode checkedAt screenshotUrl')
            .exec();

        // Execute all aggregation promises concurrently
        const [
            totalChecks,
            successfulChecks,
            failedChecks,
            statusCodeDistribution,
            uptimePerUrl,
            checksOverTime,
            recentIssues,
        ] = await Promise.all([
            totalChecksPromise,
            successfulChecksPromise,
            failedChecksPromise,
            statusCodeDistributionPromise,
            uptimePerUrlPromise,
            checksOverTimePromise,
            recentIssuesPromise,
        ]);

        // Calculate success and failure percentages
        const successPercentage = totalChecks > 0 ? ((successfulChecks / totalChecks) * 100).toFixed(2) : '0';
        const failurePercentage = totalChecks > 0 ? ((failedChecks / totalChecks) * 100).toFixed(2) : '0';

        // Structure the analytics response
        const analytics = {
            totalChecks,
            successfulChecks,
            successPercentage: `${successPercentage}%`,
            failedChecks,
            failurePercentage: `${failurePercentage}%`,
            statusCodeDistribution: statusCodeDistribution.map(item => ({
                statusCode: item._id,
                count: item.count,
                percentage: totalChecks > 0 ? `${((item.count / totalChecks) * 100).toFixed(2)}%` : '0%',
            })),
            uptimePerUrl: uptimePerUrl.map(item => ({
                url: item._id,
                successCount: item.successCount,
                totalCount: item.totalCount,
                uptimePercentage: `${item.uptimePercentage.toFixed(2)}%`,
            })),
            checksOverTime: checksOverTime.map(item => ({
                period: formatPeriod(item._id, groupBy),
                count: item.total,
            })),
            recentIssues,
        };

        res.status(200).json({ analytics });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({
                message: 'Invalid query parameters',
                errors: error.errors.map((err) => ({
                    field: err.path.join('.'),
                    message: err.message,
                })),
            });
        }

        logger.error('Get Analytics Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

/**
 * Helper Functions
 */

/**
 * Formats the period based on the groupBy parameter.
 * @param {Object} periodObj - The period object from aggregation.
 * @param {string} groupBy - 'day', 'week', or 'month'.
 * @returns {string} - Formatted period string.
 */
const formatPeriod = (periodObj, groupBy) => {
    const { year, month, week, day } = periodObj;
    switch (groupBy) {
        case 'day':
            return `${month}/${day}/${year}`;
        case 'week':
            return `Week ${week}, ${year}`;
        case 'month':
            return `${month}/${year}`;
        default:
            return `${month}/${day}/${year}`;
    }
};

/**
 * Constructs the period expression based on groupBy.
 * @param {string} groupBy - 'day', 'week', or 'month'.
 * @returns {Object} - MongoDB aggregation projection object.
 */
const getPeriodExpression = (groupBy) => {
    switch (groupBy) {
        case 'day':
            return {
                day: { $dayOfMonth: '$checkedAt' },
                month: { $month: '$checkedAt' },
                year: { $year: '$checkedAt' },
            };
        case 'week':
            return {
                week: { $week: '$checkedAt' },
                year: { $year: '$checkedAt' },
            };
        case 'month':
            return {
                month: { $month: '$checkedAt' },
                year: { $year: '$checkedAt' },
            };
        default:
            return {
                day: { $dayOfMonth: '$checkedAt' },
                month: { $month: '$checkedAt' },
                year: { $year: '$checkedAt' },
            };
    }
};

"""
"""
// models/Log.js

const mongoose = require('mongoose');

const logSchema = new mongoose.Schema({
    user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
    url: { type: String, required: true },
    statusCode: { type: Number, required: true },
    checkedAt: { type: Date, default: Date.now },
    screenshotUrl: { type: String, default: '' }, // Relative path to the screenshot
}, { timestamps: true });


// Indexes for efficient querying
logSchema.index({ user: 1, checkedAt: -1 });
logSchema.index({ user: 1, url: 1 });
logSchema.index({ user: 1, statusCode: 1 });

module.exports = mongoose.model('Log', logSchema);
""
""
const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    username: { type: String, unique: true, sparse: true, minlength: 3, maxlength: 30 },
    email: { type: String, unique: true, sparse: true, maxlength: 100 },
    password: { type: String, required: true, minlength: 6 },
    listOfUrls: { type: [String], default: [] },
    timePeriod: { 
        type: String, 
        enum: ['30s', '1m', '3m', '5m', '10m', '1h'], 
        default: '1m' 
    },
    emailSend: { type: Boolean, default: false },
    verificationToken: { type: String },
    verified: { type: Boolean, default: false },
}, { timestamps: true });

// Adding indexes for sparse unique fields
userSchema.index({ username: 1 }, { unique: true, sparse: true });
userSchema.index({ email: 1 }, { unique: true, sparse: true });

module.exports = mongoose.model('User', userSchema);
"""
"""
// services/monitorService.js

const axios = require('axios');
const cron = require('node-cron');
const Log = require('../models/Log');
const screenshotService = require('./screenshotService');
const emailService = require('./emailService');
const logger = require('../utils/logger');

// Helper: Convert time period to cron expression
const timePeriodToCron = (timePeriod) => {
    switch (timePeriod) {
        case '1m':
            return '*/1 * * * *';
        case '3m':
            return '*/3 * * * *';
        case '5m':
            return '*/5 * * * *';
        case '10m':
            return '*/10 * * * *';
        case '1h':
            return '0 * * * *';
        default:
            return '*/1 * * * *'; // Default to every minute
    }
};

// In-memory storage for cron jobs and intervals
const userJobs = new Map();
const userIntervals = new Map();

// In-memory storage for notification timers
// Structure: { userId: { url: timeoutObject } }
const notificationTimers = new Map();

/**
 * Function to perform checks on user's URLs.
 * Logs all status codes, handles notifications for non-2xx responses,
 * and captures screenshots for error notifications.
 *
 * @param {Object} user - The user object containing monitoring details.
 */
const performChecks = async (user) => {
    for (const url of user.listOfUrls) {
        try {
            const response = await axios.get(url, { timeout: 10000 });
            const statusCode = response.status;

            // Log successful check with no screenshot
            await logStatus(user._id, url, statusCode, "None");

            if (statusCode < 200 || statusCode >= 300) {
                logger.warn(`URL check failed for ${url} with status code ${statusCode}`);

                if (isNotificationPending(user._id.toString(), url)) {
                    logger.info(`Notification already pending for ${url}. Skipping email.`);
                    continue;
                }

                const screenshotUrl = await screenshotService.takeScreenshot(url);
                await emailService.sendErrorNotification(user.email, url, statusCode, screenshotUrl);
                await logStatus(user._id, url, statusCode, screenshotUrl); // Log with screenshot URL

                setNotificationTimer(user._id.toString(), url, 10 * 60 * 1000); // 10 minutes
            } else {
                logger.info(`URL check successful for ${url} with status code ${statusCode}`);
                clearNotificationTimer(user._id.toString(), url);
            }
        } catch (error) {
            let statusCode = error.response ? error.response.status : 0;
            let screenshotUrl = 'None';

            if (statusCode !== 0) {
                try {
                    screenshotUrl = await screenshotService.takeScreenshot(url);
                    logger.info(`Screenshot captured for ${url}`);
                } catch (screenshotError) {
                    logger.error(`Failed to take screenshot for ${url}: ${screenshotError.message}`);
                }
            }

            await logStatus(user._id, url, statusCode, screenshotUrl); // Log with or without screenshot
            if (!isNotificationPending(user._id.toString(), url)) {
                await emailService.sendErrorNotification(user.email, url, statusCode, screenshotUrl);
                setNotificationTimer(user._id.toString(), url, 10 * 60 * 1000);
            }
        }
    }
};

/**
 * Logs the status of the URL check to the database.
 *
 * @param {ObjectId} userId - The ID of the user.
 * @param {string} url - The URL that was checked.
 * @param {number} statusCode - The HTTP status code returned.
 */
const logStatus = async (userId, url, statusCode, screenshotUrl) => {
    try {
        const log = new Log({
            user: userId,
            url,
            statusCode,
            screenshotUrl,
            timestamp: new Date(),
        });
        await log.save();
        logger.info(`Logged status for ${url} with status code ${statusCode} and screenshot URL: ${screenshotUrl}`);
    } catch (logError) {
        logger.error(`Failed to log status for ${url}: ${logError.message}`);
    }
};

// Function to start monitoring for a user
const startMonitoring = (user) => {
    if (!user.verified) {
        logger.warn(`Attempted to start monitoring for unverified user: ${user.username}`);
        throw new Error('Email not verified. Please verify your email before starting monitoring.');
    }

    if (!user.listOfUrls || user.listOfUrls.length === 0) return;

    // Clear existing jobs or intervals to prevent duplicates
    stopMonitoring(user);

    if (user.timePeriod === '30s') {
        // node-cron doesn't support seconds intervals, use setInterval
        const interval = setInterval(() => {
            performChecks(user);
        }, 30000); // 30 seconds

        userIntervals.set(user._id.toString(), interval);
        logger.info(`Started 30s interval monitoring for user ${user.username}`);
    } else {
        const cronExpression = timePeriodToCron(user.timePeriod);
        if (!cronExpression) return;

        const job = cron.schedule(cronExpression, () => {
            performChecks(user);
        }, {
            scheduled: true,
            timezone: "UTC",
        });

        userJobs.set(user._id.toString(), job);
        logger.info(`Started cron job (${cronExpression}) monitoring for user ${user.username}`);
    }
};

// Function to stop monitoring for a user
const stopMonitoring = (user) => {
    const userId = user._id.toString();

    if (userJobs.has(userId)) {
        const job = userJobs.get(userId);
        job.stop();
        userJobs.delete(userId);
        logger.info(`Stopped cron job monitoring for user ${user.username}`);
    }

    if (userIntervals.has(userId)) {
        clearInterval(userIntervals.get(userId));
        userIntervals.delete(userId);
        logger.info(`Stopped interval monitoring for user ${user.username}`);
    }

    // Also clear any pending notification timers
    if (notificationTimers.has(userId)) {
        Object.values(notificationTimers.get(userId)).forEach(timeout => clearTimeout(timeout));
        notificationTimers.delete(userId);
        logger.info(`Cleared notification timers for user ${user.username}`);
    }
};

// Function to restart monitoring (used when settings are updated)
const restartMonitoring = (user) => {
    if (!user.verified) {
        logger.warn(`Attempted to restart monitoring for unverified user: ${user.username}`);
        throw new Error('Email not verified. Please verify your email before restarting monitoring.');
    }
    startMonitoring(user);
};

// Function to check if monitoring is active for a user
const isMonitoringActive = (userId) => {
    return userJobs.has(userId) || userIntervals.has(userId);
};

// Function to check if a notification is pending for a URL
const isNotificationPending = (userId, url) => {
    if (!notificationTimers.has(userId)) return false;
    const userTimers = notificationTimers.get(userId);
    return userTimers.hasOwnProperty(url);
};

// Function to set a notification timer for a URL
const setNotificationTimer = (userId, url, timeout) => {
    if (!notificationTimers.has(userId)) {
        notificationTimers.set(userId, {});
    }
    const userTimers = notificationTimers.get(userId);
    userTimers[url] = setTimeout(() => {
        // Timer expired, remove the pending notification
        if (notificationTimers.has(userId)) {
            delete notificationTimers.get(userId)[url];
            logger.info(`Notification timer expired for ${url}`);
            // Optionally, notify the user that monitoring is active again
            // Example:
            // emailService.sendRecoveryNotification(user.email, url);
        }
    }, timeout);
};

// Function to clear notification timer (called when URL recovers)
const clearNotificationTimer = (userId, url) => {
    if (!notificationTimers.has(userId)) return;
    const userTimers = notificationTimers.get(userId);
    if (userTimers.hasOwnProperty(url)) {
        clearTimeout(userTimers[url]);
        delete userTimers[url];
        logger.info(`Cleared notification timer for ${url}`);
    }
};

// Initialize monitoring for existing users on server start
const initializeMonitoring = async () => {
    const User = require('../models/User'); // Avoid circular dependency
    try {
        const users = await User.find({ verified: true }); // Only initialize for verified users
        users.forEach(user => {
            startMonitoring(user);
        });
        logger.info('Initialized monitoring for existing verified users');
    } catch (error) {
        logger.error('Error initializing monitoring:', error);
    }
};

module.exports = {
    startMonitoring,
    stopMonitoring,
    restartMonitoring,
    initializeMonitoring,
    isMonitoringActive,
};
"""
"""
// services/screenshotService.js

const puppeteer = require('puppeteer');
const cloudinary = require('../config/cloudinary');
const sharp = require('sharp');
const logger = require('../utils/logger');
const streamifier = require('streamifier');

// Initialize Puppeteer browser instance
let browserInstance = null;

const initBrowser = async () => {
  if (!browserInstance) {
    browserInstance = await puppeteer.launch({ args: ['--no-sandbox'] });
    logger.info('Puppeteer browser launched');
  }
  return browserInstance;
};

// Function to take a screenshot, compress, upload to Cloudinary, and return the URL
const takeScreenshot = async (url) => {
  try {
    const browser = await initBrowser();
    const page = await browser.newPage();

    // Set a reasonable viewport size
    await page.setViewport({ width: 1280, height: 800 });

    // Navigate to the URL
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }); // 30 seconds timeout

    // Capture the screenshot as a buffer
    const screenshotBuffer = await page.screenshot({ fullPage: true });

    await page.close();

    logger.info(`Screenshot captured for ${url}`);

    // Compress the image using Sharp
    const compressedBuffer = await sharp(screenshotBuffer)
      .jpeg({ quality: 20 }) // Adjust quality as needed (30 for high compression)
      .toBuffer();

    logger.info(`Screenshot compressed for ${url}`);

    // Generate a unique filename
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const sanitizedUrl = url.replace(/[^a-zA-Z0-9]/g, '_');
    const filename = `${sanitizedUrl}_${timestamp}`; // Removed extension

    // Upload the compressed image to Cloudinary using a single upload_stream
    const uploadPromise = new Promise((resolve, reject) => {
      const stream = cloudinary.uploader.upload_stream(
        {
          folder: 'screenshots', // Optional: specify a folder in Cloudinary
          public_id: filename,
          resource_type: 'image',
          format: 'jpg', // Specify the format to ensure consistent extension
        },
        (error, result) => {
          if (error) {
            logger.error(`Cloudinary upload error for ${url}: ${error.message}`);
            return reject(error);
          } else {
            logger.info(`Screenshot uploaded to Cloudinary: ${result.secure_url}`);
            return resolve(result.secure_url);
          }
        }
      );
      streamifier.createReadStream(compressedBuffer).pipe(stream);
    });

    const cloudinaryUrl = await uploadPromise;

    return cloudinaryUrl; // Return the Cloudinary URL
  } catch (error) {
    logger.error(`Error taking screenshot for ${url}: ${error.message}`);
    throw error;
  }
};

module.exports = {
  takeScreenshot,
};
"""