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);
"""
"""