remove phno entirely not equired anywhere 
"""
const { z } = require('zod');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const monitorService = require('../services/monitorService');
const logger = require('../utils/logger');
const crypto = require('crypto');
const { sendVerificationEmail } = require('../services/emailService')
// Zod Schemas
const urlSchema = z.string().url().trim();
const timePeriodSchema = z.enum(['30s', '1m', '3m', '5m', '10m', '1h']);
const phoneSchema = z.string().regex(/^\+?[\d\s-()]{10,}$/).optional();

const signupSchema = z.object({
    username: z.string().min(3).max(30).trim(),
    email: z.string().email().toLowerCase().trim(),
    password: z.string().min(8)
        .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
            'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character'),
    listOfUrls: z.array(urlSchema).default([]),
    timePeriod: timePeriodSchema.default('1m'),
    emailSend: z.boolean().default(false),
    phoneNo: phoneSchema.default(''),
});

const loginSchema = z.object({
    identifier: z.string().min(3).trim(),
    password: z.string().min(8),
});

const verifyEmailSchema = z.object({
    token: z.string().min(32),
});


exports.signup = async (req, res) => {
    try {
        // Parse and validate user input
        const parsedData = signupSchema.parse(req.body);
        const { username, email, password, listOfUrls, timePeriod, emailSend, phoneNo } = parsedData;

        // Check if user already exists
        const existingUser = await User.findOne({
            $or: [{ username }, { email }]
        });

        if (existingUser) {
            return res.status(409).json({
                message: 'Account already exists',
                field: existingUser.email === email ? 'email' : 'username'
            });
        }

        // Hash the password
        const hashedPassword = await bcrypt.hash(password, 12);
        const verificationToken = crypto.randomBytes(32).toString('hex');

        // Create a new user, including phoneNo only if it's provided
        const user = new User({
            username,
            email,
            password: hashedPassword,
            listOfUrls,
            timePeriod,
            emailSend,
            verificationToken,
            verified: false,
            ...(phoneNo && { phoneNo }) // Add phoneNo if present
        });

        await user.save();

        // Start monitoring service
        await monitorService.startMonitoring(user);

        // Send verification email
        await sendVerificationEmail(email, verificationToken);

        // Generate JWT
        const token = jwt.sign(
            {
                id: user._id,
                username: user.username,
                email: user.email
            },
            process.env.JWT_SECRET,
            { expiresIn: '24h' }
        );

        res.status(201).json({
            message: 'Registration successful. Please verify your email.',
            token,
            user: {
                id: user._id,
                username: user.username,
                email: user.email,
                verified: false,
            }
        });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({
                message: 'Validation failed',
                errors: error.errors.map(err => ({
                    field: err.path.join('.'),
                    message: err.message
                }))
            });
        }
        logger.error('Signup Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

exports.login = async (req, res) => {
    try {
        const parsedData = loginSchema.parse(req.body);
        const { identifier, password } = parsedData;

        // Find user by email or username
        const user = await User.findOne({
            $or: [
                { email: identifier.toLowerCase() },
                { username: identifier }
            ]
        });

        if (!user) {
            return res.status(401).json({ message: 'Invalid credentials' });
        }

        // Verify password
        const isValidPassword = await bcrypt.compare(password, user.password);
        if (!isValidPassword) {
            return res.status(401).json({ message: 'Invalid credentials' });
        }

        // Generate JWT
        const token = jwt.sign(
            { 
                id: user._id,
                username: user.username,
                email: user.email 
            },
            process.env.JWT_SECRET,
            { expiresIn: '24h' }
        );

        res.status(200).json({
            message: 'Login successful',
            token,
            user: {
                id: user._id,
                username: user.username,
                email: user.email,
                verified: user.verified
            }
        });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({
                message: 'Validation failed',
                errors: error.errors.map(err => ({
                    field: err.path.join('.'),
                    message: err.message
                }))
            });
        }
        logger.error('Login Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

exports.verifyEmail = async (req, res) => {
    try {
        const { token } = verifyEmailSchema.parse(req.body);

        const user = await User.findOne({ 
            verificationToken: token,
            verified: false
        });

        if (!user) {
            return res.status(400).json({ message: 'Invalid or expired verification token' });
        }

        user.verified = true;
        user.verificationToken = undefined;
        await user.save();

        res.status(200).json({ message: 'Email verified successfully' });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({
                message: 'Validation failed',
                errors: error.errors.map(err => ({
                    field: err.path.join('.'),
                    message: err.message
                }))
            });
        }
        logger.error('Email Verification Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

exports.checkVerificationStatus = async (req, res) => {
    try {
        const userId = z.string().min(1).parse(req.params.userId);

        const user = await User.findById(userId).select('verified email');
        if (!user) {
            return res.status(404).json({ message: 'User not found' });
        }

        res.status(200).json({
            verified: user.verified,
            email: user.email
        });
    } catch (error) {
        if (error instanceof z.ZodError) {
            return res.status(400).json({ message: 'Invalid user ID' });
        }
        logger.error('Check Verification Status Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};
"""
"""
// models/User.js

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 },
    phoneNo: { type: String, default: '' },
    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);
"""
""
// controllers/userController.js

const { z } = require('zod');
const User = require('../models/User');
const Log = require('../models/Log');
const monitorService = require('../services/monitorService');
const logger = require('../utils/logger');

// Zod Schemas
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(),
    phoneNo: z.string().optional(),
});

const getLogsQuerySchema = z.object({
    page: z.string(),
    limit: z.string(),
});

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' });

        // Restart monitoring with updated settings
        monitorService.restartMonitoring(updatedUser);

        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' });
    }
};

exports.getUserLogs = async (req, res) => {
    try {
        // Validate query parameters
        const parsedQuery = getLogsQuerySchema.parse(req.query);
        const page = parseInt(parsedQuery.page) || 1;
        const limit = parseInt(parsedQuery.limit) || 20;
        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);

        // 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' });
    }
};