require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const crypto = require('crypto');
const { Resend } = require('resend');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const helmet = require('helmet');

const { User, Investment, Transaction, Setting, Withdrawal, WalletRecommitment } = require('./models');
const { uploadProof } = require('./cloudinary');

const app = express();
const PORT = process.env.PORT || 3000;

const MONGO_URI = process.env.MONGO_URI || "mongodb+srv://dips94384_db_user:gEEXFR57ILCJ3J8N@cluster0.2qqaml2.mongodb.net/";
const JWT_SECRET = process.env.JWT_SECRET || "change_this_to_a_very_long_random_secure_string";
const RESEND_API_KEY = process.env.RESEND_API_KEY || 're_SY2Sauzt_MkUK3Hjkx17exowf3DNidQzp';
const EMAIL_FROM = process.env.EMAIL_FROM || 'supports@premierequation.xyz';
const ADMIN_EMAIL = process.env.ADMIN_EMAIL || 'greencorner7@gmail.com';

const resend = new Resend(RESEND_API_KEY);

app.use(helmet({
    contentSecurityPolicy: false,
}));
app.use(cors());
app.use(express.json({ limit: '50mb' }));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(express.static(path.join(__dirname, 'public')));

mongoose.connect(MONGO_URI, {
    serverSelectionTimeoutMS: 5000,
    socketTimeoutMS: 45000,
    family: 4
})
    .then(async () => {
        console.log('✅ MongoDB Connected Successfully');
        initializeDefaults();
    })
    .catch(err => {
        console.error("❌ MONGODB CONNECTION ERROR:");
        console.error(`Name: ${err.name}`);
        console.error(`Message: ${err.message}`);

        if (err.message.includes('ETIMEDOUT') || err.message.includes('buffering timed out')) {
            console.error("👉 CAUSE: Your hosting provider (likely cPanel) is blocking Port 27017.");
            console.error("👉 FIX: You must whitelist your server IP in MongoDB Atlas OR move to a VPS/Node-friendly host.");
        } else if (err.message.includes('bad auth')) {
            console.error("👉 CAUSE: Incorrect Username or Password.");
        }
    });

function authenticateToken(req, res, next) {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) return res.status(401).json({ success: false, message: 'Access Denied. Please login.' });

    jwt.verify(token, JWT_SECRET, (err, user) => {
        if (err) return res.status(403).json({ success: false, message: 'Invalid or expired token.' });
        req.user = user;
        next();
    });
}

function verifyAdmin(req, res, next) {
    if (!req.user || !req.user.isAdmin) {
        return res.status(403).json({ success: false, message: 'Admin privileges required.' });
    }
    next();
}

async function initializeDefaults() {
    const adminEmail = 'greencorner7@gmail.com';
    const adminUser = await User.findOne({ email: adminEmail });

    if (!adminUser) {
        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash('ONline25', salt);

        const newAdmin = new User({
            fullName: 'System Admin',
            email: adminEmail,
            password: hashedPassword,
            isAdmin: true,
            mobile: '0000000000',
            referralCode: 'ADMIN01',
            isVerified: true
        });
        await newAdmin.save();
        console.log('Admin account created.');
    } else {
        if (!adminUser.isVerified) {
            adminUser.isVerified = true;
            await adminUser.save();
            console.log('✅ Existing Admin account verified automatically.');
        }
    }

    const settingsExists = await Setting.findOne({ type: 'config' });
    if (!settingsExists) {
        const defaultSettings = new Setting({
            packages: [
                { id: 1, name: 'Apex', returnRate: 30, duration: 7, enabled: true },
                { id: 2, name: 'Star', returnRate: 10, duration: 3, enabled: true },
                { id: 3, name: 'Premier', returnRate: 20, duration: 5, enabled: true }
            ],
            referralBonus: { level1: 10, level2: 2 },
            recommitment: { enabled: true, percentage: 50 }
        });
        await defaultSettings.save();
        console.log('Default settings created.');
    } else if (!settingsExists.recommitment) {
        settingsExists.recommitment = { enabled: true, percentage: 50 };
        await settingsExists.save();
        console.log('Settings updated with default recommitment policy.');
    }
}

function generateReferralCode() {
    return Math.random().toString(36).substring(2, 8).toUpperCase();
}

const MATH_QUESTIONS = [
    { id: 1, q: "If f(x) = 3x² - 4x + 1, find f'(2).", a: "8" },
    { id: 2, q: "Evaluate ∫(0 to 1) 4x³ dx.", a: "1" },
    { id: 3, q: "What is the sum of the roots of 2x² - 8x + 5 = 0?", a: "4" },
    { id: 4, q: "Calculate the sum of interior angles of a Hexagon (in degrees).", a: "720" },
    { id: 5, q: "Find the remainder when x³ - 2x² + x + 4 is divided by (x - 1).", a: "4" },
    { id: 6, q: "If y = sin(2x), what is dy/dx at x = 0?", a: "2" },
    { id: 7, q: "Find the discriminant of x² + 4x + 4 = 0.", a: "0" },
    { id: 8, q: "Evaluate ∫(1 to 2) 2x dx.", a: "3" },
    { id: 9, q: "How many diagonals does a regular pentagon have?", a: "5" },
    { id: 10, q: "If f(x) = x³ + 1, find f''(1).", a: "6" }
];

function getDailyQuestion() {
    const today = new Date();
    const dateStr = `${today.getFullYear()}${today.getMonth()}${today.getDate()}`;
    const index = parseInt(dateStr) % MATH_QUESTIONS.length;
    return MATH_QUESTIONS[index];
}

app.get('/api/challenge/today', authenticateToken, async (req, res) => {
    try {
        const user = await User.findById(req.user._id);
        const today = new Date().setHours(0, 0, 0, 0);
        const lastAttempt = user.lastChallengeAttempt ? new Date(user.lastChallengeAttempt).setHours(0, 0, 0, 0) : 0;

        const alreadyPlayed = lastAttempt === today;
        const questionData = getDailyQuestion();

        res.json({
            question: questionData.q,
            alreadyPlayed: alreadyPlayed
        });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/challenge/submit', authenticateToken, async (req, res) => {
    try {
        const { answer } = req.body;
        const user = await User.findById(req.user._id);

        const today = new Date().setHours(0, 0, 0, 0);
        const lastAttempt = user.lastChallengeAttempt ? new Date(user.lastChallengeAttempt).setHours(0, 0, 0, 0) : 0;

        if (lastAttempt === today) {
            return res.status(400).json({ success: false, message: "You have already attempted today's challenge." });
        }

        const questionData = getDailyQuestion();
        const cleanAnswer = String(answer).trim().toLowerCase();
        const isCorrect = cleanAnswer === String(questionData.a).toLowerCase();

        user.lastChallengeAttempt = new Date();

        let message = "Incorrect answer. Try again tomorrow!";

        if (isCorrect) {
            user.withdrawalBalance = (user.withdrawalBalance || 0) + 200;
            user.exemptWithdrawalBalance = (user.exemptWithdrawalBalance || 0) + 200;

            await new Transaction({
                userEmail: user.email,
                type: 'Math Challenge Reward',
                amount: 200,
                description: 'Daily Math Challenge Correct Answer',
                transactionType: 'credit'
            }).save();
            message = "Correct! N200 has been added to your wallet.";
        }

        await user.save();
        res.json({ success: isCorrect, message: message });

    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/auth/register', async (req, res) => {
    try {
        const { fullName, email, mobile, referralCode, bankName, accountNumber, password } = req.body;

        let referredBy = null;

        if (referralCode && referralCode.trim() !== '') {
            const referralUser = await User.findOne({ referralCode: referralCode.trim() });
            if (!referralUser) {
                return res.status(400).json({ success: false, message: 'Invalid Referral Code. Please check and try again.' });
            }
            referredBy = referralCode.trim();
        }

        const existingUser = await User.findOne({ email });
        if (existingUser) return res.status(400).json({ success: false, message: 'Email already exists' });

        const existingMobile = await User.findOne({ mobile });
        if (existingMobile) {
            return res.status(400).json({ success: false, message: 'Mobile number is already registered' });
        }

        const verificationToken = crypto.randomBytes(32).toString('hex');
        const verificationTokenExpires = Date.now() + 24 * 60 * 60 * 1000;

        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash(password, salt);

        const newUser = new User({
            fullName, email, mobile, bankName, accountNumber,
            password: hashedPassword,
            referralCode: generateReferralCode(),
            referredBy: referredBy,
            isVerified: false,
            verificationToken,
            verificationTokenExpires
        });

        await newUser.save();

        const protocol = req.headers['x-forwarded-proto'] || req.protocol;
        const host = req.headers.host;
        const verifyUrl = `${protocol}://${host}/?verifyToken=${verificationToken}`;

        await resend.emails.send({
            from: `Premier Equation <${EMAIL_FROM}>`,
            to: [email],
            subject: 'Verify Your Account',
            html: `
                <div style="font-family: Arial, sans-serif; color: #333;">
                    <h2>Welcome to Premier Equation!</h2>
                    <p>Please verify your email address to activate your account and start investing.</p>
                    <p><a href="${verifyUrl}" style="background-color: #004d40; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Verify Email</a></p>
                    <p>Or copy this link: ${verifyUrl}</p>
                    <p>This link expires in 24 hours.</p>
                </div>
            `
        });

        res.json({ success: true, message: 'Registration successful! Please check your email to verify your account.' });
    } catch (err) {
        console.error("Registration Error:", err);
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/auth/verify-email', async (req, res) => {
    try {
        const { token } = req.body;

        const user = await User.findOne({
            verificationToken: token,
            verificationTokenExpires: { $gt: Date.now() }
        });

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

        user.isVerified = true;
        user.verificationToken = undefined;
        user.verificationTokenExpires = undefined;
        await user.save();

        res.json({ success: true, message: 'Email verified successfully! You can now login.' });

    } catch (err) {
        res.status(500).json({ success: false, message: 'Server error during verification' });
    }
});

app.post('/api/auth/login', async (req, res) => {
    const { email, password } = req.body;
    try {
        const user = await User.findOne({ email });
        if (!user) return res.status(401).json({ success: false, message: 'Invalid credentials' });

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

        if (!user.isVerified) {
            return res.status(403).json({ success: false, message: 'Please verify your email address before logging in.' });
        }

        if (user.suspended) return res.status(403).json({ success: false, message: 'Account suspended' });

        const token = jwt.sign(
            { _id: user._id, email: user.email, isAdmin: user.isAdmin },
            JWT_SECRET,
            { expiresIn: '24h' }
        );

        res.json({
            success: true,
            token,
            user: {
                fullName: user.fullName,
                email: user.email,
                isAdmin: user.isAdmin,
                referralCode: user.referralCode,
                withdrawalBalance: user.withdrawalBalance,
                referralBonus: user.referralBonus
            }
        });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/auth/forgot-password', async (req, res) => {
    try {
        const { email } = req.body;
        const user = await User.findOne({ email });

        if (!user) {
            return res.json({ success: true, message: 'If an account exists, a reset link has been sent.' });
        }

        const token = crypto.randomBytes(20).toString('hex');
        user.resetPasswordToken = token;
        user.resetPasswordExpires = Date.now() + 3600000;
        await user.save();

        const protocol = req.headers['x-forwarded-proto'] || req.protocol;
        const host = req.headers.host;
        const resetUrl = `${protocol}://${host}/?resetToken=${token}`;

        const { error } = await resend.emails.send({
            from: `Premier Equation <${EMAIL_FROM}>`,
            to: [user.email],
            subject: 'Password Reset Request',
            html: `
                <div style="font-family: Arial, sans-serif; color: #333;">
                    <h2>Password Reset</h2>
                    <p>Please click on the following link to reset your password:</p>
                    <p><a href="${resetUrl}" style="background-color: #004d40; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Reset Password</a></p>
                    <p><small>${resetUrl}</small></p>
                </div>
            `
        });

        if (error) {
            console.error('Resend Error:', error);
            return res.status(500).json({ success: false, message: 'Error sending email' });
        }

        res.json({ success: true, message: 'Reset link sent to your email.' });

    } catch (err) {
        console.error(err);
        res.status(500).json({ success: false, message: 'Server error' });
    }
});

app.post('/api/auth/reset-password', async (req, res) => {
    try {
        const { token, newPassword } = req.body;

        const user = await User.findOne({
            resetPasswordToken: token,
            resetPasswordExpires: { $gt: Date.now() }
        });

        if (!user) {
            return res.status(400).json({ success: false, message: 'Token invalid or expired.' });
        }

        const salt = await bcrypt.genSalt(10);
        user.password = await bcrypt.hash(newPassword, salt);
        user.resetPasswordToken = undefined;
        user.resetPasswordExpires = undefined;

        await user.save();
        res.json({ success: true, message: 'Password updated! Please login.' });

    } catch (err) {
        res.status(500).json({ success: false, message: 'Server error' });
    }
});

app.get('/api/data/:email', authenticateToken, async (req, res) => {
    try {
        const { email } = req.params;

        if (req.user.email !== email && !req.user.isAdmin) {
            return res.status(403).json({ error: 'Unauthorized access to data' });
        }

        const user = await User.findOne({ email });
        if (!user) return res.status(404).json({ error: 'User not found' });

        const investments = await Investment.find({ userEmail: email, deleted: { $ne: true } });
        const transactions = await Transaction.find({ userEmail: email }).sort({ date: -1 });
        const settings = await Setting.findOne({ type: 'config' });

        res.json({
            user: {
                fullName: user.fullName,
                email: user.email,
                isAdmin: user.isAdmin,
                referralCode: user.referralCode,
                withdrawalBalance: user.withdrawalBalance,
                referralBonus: user.referralBonus,
                suspended: user.suspended,
                isEligibleForWithdrawal: user.isEligibleForWithdrawal,
                pendingRecommitmentAmount: user.pendingRecommitmentAmount,
                cycleSettlementRequired: user.cycleSettlementRequired
            },
            investments,
            transactions,
            packages: settings ? settings.packages : []
        });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/invest', authenticateToken, async (req, res) => {
    const { email, packageName, amount, duration, returnRate, proofImage, paymentMethod, isRecommitmentCycle } = req.body;

    if (req.user.email !== email) return res.status(403).json({ error: 'Identity mismatch' });

    if (packageName === 'Star' && amount > 50000) {
        return res.status(400).json({ success: false, message: 'Star package investment cannot exceed N50,000.' });
    }

    try {
        const previousInvestments = await Investment.find({
            userEmail: email,
            status: { $in: ['Active', 'Completed'] },
            deleted: { $ne: true }
        }).sort({ amount: -1 }).limit(1);

        if (previousInvestments.length > 0) {
            const highestPreviousAmount = previousInvestments[0].amount;
            if (amount < highestPreviousAmount) {
                return res.status(400).json({
                    success: false,
                    message: `New investment (N${amount.toLocaleString()}) cannot be lower than your previous highest investment (N${highestPreviousAmount.toLocaleString()}).`
                });
            }
        }
    } catch (error) {
        console.error('Error checking previous investments:', error);
    }

    try {
        let proofUrl = '';
        let status = 'Pending';
        let transactionDescription = `Investment request in ${packageName}`;

        if (paymentMethod === 'Wallet') {
            const user = await User.findOne({ email });
            if (user.withdrawalBalance < amount) {
                return res.json({ success: false, message: 'Insufficient wallet balance.' });
            }

            await User.updateOne({ email }, { $inc: { withdrawalBalance: -amount } });

            const updatedUser = await User.findOne({ email });
            if (updatedUser.exemptWithdrawalBalance > updatedUser.withdrawalBalance) {
                updatedUser.exemptWithdrawalBalance = updatedUser.withdrawalBalance;
                await updatedUser.save();
            }

            status = 'Pending';
            transactionDescription = `Investment Request in ${packageName} (Wallet)`;
            proofUrl = 'Wallet-Payment';

            const profit = amount * (returnRate / 100);
            const totalReturn = amount + profit;

            const newInv = new Investment({
                userEmail: email,
                package: packageName,
                amount,
                profit,
                totalReturn,
                returnRate,
                duration,
                proofImage: proofUrl,
                status: 'Pending',
                paymentMethod: 'Wallet',
                isRecommitmentCycle: isRecommitmentCycle || false,
                investmentCycle: isRecommitmentCycle ? 2 : 1
            });
            await newInv.save();

            const trans = new Transaction({
                userEmail: email,
                type: 'Investment Request',
                amount: amount,
                description: transactionDescription,
                transactionType: 'debit',
                status: 'Pending'
            });
            await trans.save();

            return res.json({ success: true, message: 'Investment request submitted! Waiting for admin approval.' });
        }

        if (proofImage) {
            try {
                proofUrl = await uploadProof(proofImage);
            } catch (uploadError) {
                return res.status(500).json({ error: 'Image upload failed: ' + uploadError.message });
            }
        }

        const profit = amount * (returnRate / 100);
        const totalReturn = amount + profit;

        const newInv = new Investment({
            userEmail: email,
            package: packageName,
            amount,
            profit,
            totalReturn,
            returnRate,
            duration,
            proofImage: proofUrl,
            status: 'Pending',
            paymentMethod: paymentMethod || 'Manual',
            isRecommitmentCycle: isRecommitmentCycle || false,
            investmentCycle: isRecommitmentCycle ? 2 : 1
        });
        await newInv.save();

        const trans = new Transaction({
            userEmail: email,
            type: 'Investment Request',
            amount: amount,
            description: `Investment request in ${packageName}`,
            transactionType: 'debit',
            status: 'Pending'
        });
        await trans.save();

        res.json({ success: true, investment: newInv });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/withdraw/request', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;
        const { amount } = req.body;

        if (amount <= 0) return res.status(400).json({ success: false, message: 'Invalid amount' });

        const user = await User.findOne({ email });
        if (!user) return res.status(404).json({ success: false, message: 'User not found' });

        // NOTE: The previous logic for deducting from referralBonus here is superseded by the new
        // direct withdrawal route, but we keep this check for backward compatibility or if called directly.
        if (user.referralBonus >= amount) {
            user.referralBonus -= amount;
            await user.save();

            const newWithdrawal = new Withdrawal({
                userEmail: email,
                amount: amount,
                bankName: user.bankName,
                accountNumber: user.accountNumber,
                status: 'Pending',
                isExempt: true,
                note: 'Withdrawn from referral bonus (No recommitment required)'
            });
            await newWithdrawal.save();

            await new Transaction({
                userEmail: email,
                type: 'Withdrawal',
                amount: amount,
                description: 'Withdrawal Request from Referral Bonus (No recommitment required)',
                transactionType: 'debit',
                status: 'Pending'
            }).save();

            return res.json({ success: true, message: 'Referral bonus withdrawal request submitted successfully! No recommitment required.' });
        }

        let isExemptWithdrawal = false;

        if ((user.exemptWithdrawalBalance || 0) >= amount) {
            isExemptWithdrawal = true;
        }

        if (!isExemptWithdrawal) {
            if (!user.isEligibleForWithdrawal) {
                return res.status(400).json({
                    success: false,
                    message: 'You are not eligible for withdrawal. Please complete the recommitment requirement first.'
                });
            }

            if (user.cycleSettlementRequired) {
                return res.status(400).json({
                    success: false,
                    message: 'You have pending cycle settlements. Please complete cycle settlements before withdrawing.'
                });
            }

            const settings = await Setting.findOne({ type: 'config' });
            const recommitmentEnabled = settings?.recommitment?.enabled ?? true;
            const recommitmentPercent = settings?.recommitment?.percentage ?? 50;

            const hasInvestment = await Investment.findOne({
                userEmail: email,
                status: { $in: ['Active', 'Completed'] },
                deleted: { $ne: true }
            });

            if (!hasInvestment) {
                return res.status(400).json({
                    success: false,
                    message: 'Withdrawal restricted. You must have at least one active or completed investment package to withdraw funds.'
                });
            }

            if (recommitmentEnabled) {
                const lastCompletedInvestment = await Investment.findOne({
                    userEmail: email,
                    status: 'Completed',
                    withdrawn: false,
                    deleted: { $ne: true }
                }).sort({ maturityDate: -1 }).limit(1);

                if (lastCompletedInvestment) {
                    const recommitmentThreshold = lastCompletedInvestment.amount * (recommitmentPercent / 100);

                    const recommitmentInvestments = await Investment.find({
                        userEmail: email,
                        status: { $in: ['Active', 'Pending'] },
                        date: { $gt: lastCompletedInvestment.maturityDate },
                        amount: { $gte: recommitmentThreshold },
                        deleted: { $ne: true }
                    });

                    if (recommitmentInvestments.length === 0) {
                        return res.status(400).json({
                            success: false,
                            message: `Withdrawal requires recommitment of at least ${recommitmentPercent}% (N${recommitmentThreshold.toLocaleString()}) of your last completed investment (N${lastCompletedInvestment.amount.toLocaleString()}). Please invest first, then request admin approval for withdrawal.`
                        });
                    }

                    const approvedRecommitment = recommitmentInvestments.find(inv => inv.status === 'Active');
                    if (!approvedRecommitment) {
                        return res.status(400).json({
                            success: false,
                            message: 'Recommitment investment is pending admin approval. Please wait for admin verification before withdrawing.'
                        });
                    }
                }
            }
        }

        const updateOperation = {
            $inc: {
                withdrawalBalance: -amount
            }
        };

        if (isExemptWithdrawal) {
            updateOperation.$inc.exemptWithdrawalBalance = -amount;
        }

        const updatedUser = await User.findOneAndUpdate(
            { email: email, withdrawalBalance: { $gte: amount } },
            updateOperation,
            { new: true }
        );

        if (!updatedUser) {
            return res.status(400).json({ success: false, message: 'Insufficient funds or user not found' });
        }

        const newWithdrawal = new Withdrawal({
            userEmail: email,
            amount: amount,
            bankName: user.bankName,
            accountNumber: user.accountNumber,
            status: 'Pending',
            isExempt: isExemptWithdrawal
        });
        await newWithdrawal.save();

        const newTransaction = new Transaction({
            userEmail: email,
            type: 'Withdrawal',
            amount: amount,
            description: isExemptWithdrawal ? 'Withdrawal Request (Exempt/Bonus)' : 'Withdrawal Request',
            transactionType: 'debit',
            status: 'Pending'
        });
        await newTransaction.save();

        res.json({ success: true, message: 'Withdrawal request submitted successfully' });

    } catch (error) {
        console.error('Withdrawal Request Error:', error);
        res.status(500).json({ success: false, message: 'Server error processing request' });
    }
});

app.post('/api/withdraw/referral', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;
        const { amount } = req.body;
        const MIN_BONUS_WITHDRAWAL = 5000;

        if (!amount || amount < MIN_BONUS_WITHDRAWAL) {
            return res.status(400).json({
                success: false,
                message: `Minimum bonus withdrawal is N${MIN_BONUS_WITHDRAWAL.toLocaleString()}`
            });
        }

        const user = await User.findOne({ email });
        if (!user) return res.status(404).json({ success: false, message: 'User not found' });

        if (user.referralBonus < amount) {
            return res.status(400).json({
                success: false,
                message: 'Insufficient referral bonus balance.'
            });
        }

        // Deduct directly from Referral Bonus
        user.referralBonus -= amount;
        await user.save();

        // Create Withdrawal Request
        const newWithdrawal = new Withdrawal({
            userEmail: email,
            amount: amount,
            bankName: user.bankName,
            accountNumber: user.accountNumber,
            status: 'Pending',
            isExempt: true, // Bypass recommitment
            note: 'Direct Referral Bonus Withdrawal'
        });
        await newWithdrawal.save();

        // Log Transaction
        await new Transaction({
            userEmail: email,
            type: 'Withdrawal',
            amount: amount,
            description: 'Referral Bonus Withdrawal (Exempt)',
            transactionType: 'debit',
            status: 'Pending'
        }).save();

        res.json({
            success: true,
            message: 'Bonus withdrawal request submitted! Waiting for admin approval.'
        });

    } catch (error) {
        console.error('Bonus Withdrawal Error:', error);
        res.status(500).json({ success: false, message: 'Server error processing withdrawal' });
    }
});

app.get('/api/withdraw/check-recommitment', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;
        const user = await User.findOne({ email });

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

        if (user.isEligibleForWithdrawal && !user.cycleSettlementRequired) {
            return res.json({ requiresRecommitment: false });
        }

        if (user.cycleSettlementRequired) {
            return res.json({
                requiresRecommitment: false,
                requiresCycleSettlement: true,
                message: 'Cycle settlement required before withdrawal'
            });
        }

        const settings = await Setting.findOne({ type: 'config' });
        const recommitmentEnabled = settings?.recommitment?.enabled ?? true;

        if (!recommitmentEnabled) {
            return res.json({ requiresRecommitment: false });
        }

        const recommitmentPercent = settings?.recommitment?.percentage ?? 50;

        const lastCompletedInvestment = await Investment.findOne({
            userEmail: email,
            status: 'Completed',
            withdrawn: false,
            deleted: { $ne: true },
            isRecommitment: false
        }).sort({ maturityDate: -1 }).limit(1);

        if (!lastCompletedInvestment) {
            return res.json({ requiresRecommitment: false });
        }

        const recommitmentThreshold = lastCompletedInvestment.amount * (recommitmentPercent / 100);
        const recommitmentInvestments = await Investment.find({
            userEmail: email,
            status: { $in: ['Active', 'Pending'] },
            date: { $gt: lastCompletedInvestment.maturityDate },
            amount: { $gte: recommitmentThreshold },
            deleted: { $ne: true }
        });

        if (recommitmentInvestments.length === 0) {
            return res.json({
                requiresRecommitment: true,
                requiredAmount: recommitmentThreshold,
                lastInvestmentAmount: lastCompletedInvestment.amount,
                exemptBalance: user.exemptWithdrawalBalance || 0
            });
        }

        res.json({ requiresRecommitment: false });
    } catch (error) {
        res.status(500).json({ error: 'Server error checking recommitment' });
    }
});

app.post('/api/transfer-bonus', authenticateToken, async (req, res) => {
    const email = req.user.email;
    try {
        const user = await User.findOne({ email });
        const amount = user.referralBonus;

        if (amount <= 0) return res.status(400).json({ success: false, message: "No bonus to transfer" });

        const result = await User.updateOne(
            { email: email, referralBonus: amount },
            {
                $inc: {
                    withdrawalBalance: amount,
                    exemptWithdrawalBalance: amount
                },
                $set: { referralBonus: 0 }
            }
        );

        if (result.modifiedCount === 0) {
            return res.status(400).json({ success: false, message: "Transfer failed, try again." });
        }

        await new Transaction({
            userEmail: email,
            type: 'Bonus Transfer',
            amount: amount,
            description: 'Referral bonus to wallet',
            transactionType: 'credit'
        }).save();

        res.json({ success: true });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.get('/api/admin/withdrawals', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const withdrawals = await Withdrawal.find().sort({ requestDate: -1 });
        res.json(withdrawals);
    } catch (error) {
        res.status(500).json({ error: 'Failed to fetch withdrawals' });
    }
});

app.post('/api/admin/withdrawals/action', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const { withdrawalId, action } = req.body;

        const withdrawal = await Withdrawal.findById(withdrawalId);
        if (!withdrawal || withdrawal.status !== 'Pending') {
            return res.status(400).json({ success: false, message: 'Request invalid or processed' });
        }

        if (action === 'approve') {
            withdrawal.status = 'Approved';
            withdrawal.actionDate = Date.now();
            await withdrawal.save();

            await Transaction.updateMany(
                { userEmail: withdrawal.userEmail, amount: withdrawal.amount, status: 'Pending', type: 'Withdrawal' },
                { status: 'Completed' }
            );

            res.json({ success: true, message: 'Withdrawal Approved' });

        } else if (action === 'reject') {
            withdrawal.status = 'Rejected';
            withdrawal.actionDate = Date.now();
            await withdrawal.save();

            await Transaction.updateMany(
                { userEmail: withdrawal.userEmail, amount: withdrawal.amount, status: 'Pending', type: 'Withdrawal' },
                { status: 'Failed' }
            );

            const updateQuery = {
                $inc: { withdrawalBalance: withdrawal.amount }
            };

            // If it was an exempt withdrawal (like direct referral bonus), refund it correctly.
            // If it was a direct referral withdrawal, we might want to refund it back to referralBonus,
            // or just to withdrawalBalance.
            // The logic below puts it into withdrawalBalance.
            // If the user wants it back in referralBonus specifically for direct referral withdrawals,
            // we would need extra logic. However, putting it in withdrawalBalance is standard for refunds here.
            // Given the complexity, standard refund to withdrawal balance is safer unless specified otherwise.

            if (withdrawal.isExempt) {
                updateQuery.$inc.exemptWithdrawalBalance = withdrawal.amount;
            }

            // Note: If this was a direct referral withdrawal, the funds were taken from referralBonus.
            // Refunding to withdrawalBalance means they can withdraw it later (still exempt).
            // This is acceptable behavior.

            await User.updateOne(
                { email: withdrawal.userEmail },
                updateQuery
            );

            res.json({ success: true, message: 'Withdrawal Rejected and Funds Refunded' });
        }
    } catch (error) {
        res.status(500).json({ success: false, message: 'Server error' });
    }
});

app.get('/api/admin/investments/pending', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const pendingInvestments = await Investment.find({
            status: 'Pending',
            deleted: { $ne: true },
            package: { $ne: 'Wallet Recommitment' }
        }).sort({ date: -1 });
        res.json(pendingInvestments);
    } catch (error) {
        res.status(500).json({ error: 'Failed to fetch pending investments' });
    }
});

app.post('/api/admin/investments/action', authenticateToken, verifyAdmin, async (req, res) => {
    const { investmentId, action } = req.body;

    try {
        const investment = await Investment.findById(investmentId);
        if (!investment) {
            return res.status(400).json({ success: false, message: 'Invalid investment' });
        }

        if (investment.status !== 'Pending') {
            return res.status(400).json({ success: false, message: 'Investment already processed' });
        }

        const user = await User.findOne({ email: investment.userEmail });
        if (!user) return res.status(404).json({ success: false, message: 'User not found' });

        if (action === 'approve') {
            investment.status = 'Active';
            const startDate = new Date();
            const maturityDate = new Date();
            maturityDate.setDate(startDate.getDate() + investment.duration);
            investment.date = startDate;
            investment.maturityDate = maturityDate;
            await investment.save();

            await Transaction.updateMany(
                { userEmail: investment.userEmail, amount: investment.amount, type: 'Investment Request', status: 'Pending' },
                { status: 'Completed', type: 'Investment', description: `Investment in ${investment.package} (Active)` }
            );

            const settings = await Setting.findOne({ type: 'config' });
            if (user.referredBy && settings) {
                const referrerL1 = await User.findOne({ referralCode: user.referredBy });
                if (referrerL1) {
                    const bonusL1 = investment.amount * (settings.referralBonus.level1 / 100);

                    await User.updateOne(
                        { _id: referrerL1._id },
                        { $inc: { referralBonus: bonusL1 } }
                    );

                    await new Transaction({
                        userEmail: referrerL1.email,
                        type: 'Referral Bonus',
                        amount: bonusL1,
                        description: `Level 1 bonus from ${user.fullName}`,
                        transactionType: 'credit'
                    }).save();

                    if (referrerL1.referredBy) {
                        const referrerL2 = await User.findOne({ referralCode: referrerL1.referredBy });
                        if (referrerL2) {
                            const bonusL2 = investment.amount * (settings.referralBonus.level2 / 100);
                            await User.updateOne(
                                { _id: referrerL2._id },
                                { $inc: { referralBonus: bonusL2 } }
                            );
                            await new Transaction({
                                userEmail: referrerL2.email,
                                type: 'Referral Bonus',
                                amount: bonusL2,
                                description: `Level 2 bonus from ${user.fullName}`,
                                transactionType: 'credit'
                            }).save();
                        }
                    }
                }
            }

            if (investment.isRecommitment && investment.package === 'Wallet Recommitment') {
                const walletRecommitment = await WalletRecommitment.findOne({
                    recommitmentInvestmentId: investment._id
                });

                if (walletRecommitment) {
                    walletRecommitment.status = 'Approved';
                    walletRecommitment.approvedAt = new Date();
                    walletRecommitment.approvedBy = req.user.email;
                    await walletRecommitment.save();

                    await User.updateOne(
                        { email: investment.userEmail },
                        {
                            $set: {
                                isEligibleForWithdrawal: true,
                                pendingRecommitmentAmount: 0
                            }
                        }
                    );

                    await Transaction.updateMany(
                        {
                            userEmail: investment.userEmail,
                            amount: walletRecommitment.walletDeduction,
                            type: 'Wallet Recommitment Deduction',
                            status: 'Pending'
                        },
                        { status: 'Completed' }
                    );
                }
            }

            res.json({ success: true, message: 'Investment Approved' });

        } else if (action === 'reject') {
            investment.status = 'Rejected';
            await investment.save();

            await Transaction.updateMany(
                { userEmail: investment.userEmail, amount: investment.amount, type: 'Investment Request', status: 'Pending' },
                { status: 'Failed', description: `Investment rejected` }
            );

            if (investment.isRecommitment && investment.package === 'Wallet Recommitment') {
                const walletRecommitment = await WalletRecommitment.findOne({
                    recommitmentInvestmentId: investment._id
                });

                if (walletRecommitment) {
                    walletRecommitment.status = 'Rejected';
                    await walletRecommitment.save();

                    await User.updateOne(
                        { email: investment.userEmail },
                        {
                            $inc: { withdrawalBalance: walletRecommitment.walletDeduction },
                            $set: { pendingRecommitmentAmount: 0 }
                        }
                    );

                    await new Transaction({
                        userEmail: investment.userEmail,
                        type: 'Recommitment Refund',
                        amount: walletRecommitment.walletDeduction,
                        description: 'Refund for rejected wallet recommitment',
                        transactionType: 'credit',
                        status: 'Completed'
                    }).save();

                    await Transaction.updateMany(
                        {
                            userEmail: investment.userEmail,
                            amount: walletRecommitment.walletDeduction,
                            type: 'Wallet Recommitment Deduction',
                            status: 'Pending'
                        },
                        { status: 'Failed' }
                    );
                }
            }

            if (investment.paymentMethod === 'Wallet') {
                await User.updateOne(
                    { email: investment.userEmail },
                    { $inc: { withdrawalBalance: investment.amount } }
                );

                const updatedUser = await User.findOne({ email: investment.userEmail });
                if (updatedUser.exemptWithdrawalBalance > updatedUser.withdrawalBalance) {
                    updatedUser.exemptWithdrawalBalance = updatedUser.withdrawalBalance;
                    await updatedUser.save();
                }

                await new Transaction({
                    userEmail: investment.userEmail,
                    type: 'Refund',
                    amount: investment.amount,
                    description: `Refund for rejected ${investment.package} investment`,
                    transactionType: 'credit',
                    status: 'Completed'
                }).save();
            }

            res.json({ success: true, message: 'Investment Rejected' });
        }
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.get('/api/admin/users/:email/investments', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const { email } = req.params;

        const user = await User.findOne({ email });
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found' });
        }

        const investments = await Investment.find({
            userEmail: email,
            deleted: { $ne: true }
        }).sort({ date: -1 });

        res.json({
            success: true,
            user: {
                fullName: user.fullName,
                email: user.email,
                bankName: user.bankName,
                accountNumber: user.accountNumber
            },
            investments: investments
        });

    } catch (err) {
        console.error('Error fetching user investments:', err);
        res.status(500).json({ success: false, message: 'Server error fetching investments' });
    }
});

app.delete('/api/admin/investments/:id', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const investmentId = req.params.id;
        const { reason } = req.body;

        const investment = await Investment.findById(investmentId);
        if (!investment) {
            return res.status(404).json({ success: false, message: 'Investment not found.' });
        }

        const userEmail = investment.userEmail;
        const user = await User.findOne({ email: userEmail });

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

        if (!['Pending', 'Active'].includes(investment.status)) {
            return res.status(400).json({
                success: false,
                message: 'Only Pending or Active investments can be deleted.'
            });
        }

        let refundAmount = 0;
        let transactionDescription = `Investment reversal for ${investment.package} package`;
        let refundProcessed = false;

        if (investment.paymentMethod === 'Wallet') {
            refundAmount = investment.amount;
            await User.updateOne(
                { email: userEmail },
                { $inc: { withdrawalBalance: refundAmount } }
            );

            const updatedUser = await User.findOne({ email: userEmail });
            if (updatedUser.exemptWithdrawalBalance > updatedUser.withdrawalBalance) {
                updatedUser.exemptWithdrawalBalance = updatedUser.withdrawalBalance;
                await updatedUser.save();
            }

            transactionDescription += ' (Wallet refund)';
            refundProcessed = true;

            await new Transaction({
                userEmail: userEmail,
                type: 'Investment Refund',
                amount: refundAmount,
                description: transactionDescription,
                transactionType: 'credit',
                status: 'Completed'
            }).save();
        } else {
            transactionDescription += ' (Completed)';

            try {
                await resend.emails.send({
                    from: `Premier Equation <${EMAIL_FROM}>`,
                    to: [ADMIN_EMAIL],
                    subject: '⚠️ Manual Refund Required - Investment Deleted',
                    html: `
                        <div style="font-family: Arial, sans-serif; color: #333;">
                            <h2>Manual Refund Required</h2>
                            <p>Investment ID: ${investmentId} has been deleted.</p>
                            <p>User: ${user.fullName} (${userEmail})</p>
                            <p>Amount: N${investment.amount.toLocaleString()}</p>
                            <p>Package: ${investment.package}</p>
                            <p>Payment Method: ${investment.paymentMethod}</p>
                            <p>Deletion Reason: ${reason || 'No reason provided'}</p>
                            <p><strong>Action Required:</strong> Process manual refund of N${investment.amount.toLocaleString()} to user's bank account.</p>
                            <p>Bank: ${user.bankName} | Account: ${user.accountNumber}</p>
                        </div>
                    `
                });
            } catch (emailError) {
                console.error('Failed to send refund notification:', emailError);
            }
        }

        await new Transaction({
            userEmail: userEmail,
            type: 'Investment Deletion',
            amount: investment.amount,
            description: transactionDescription,
            transactionType: 'credit',
            status: 'Completed'
        }).save();

        investment.deleted = true;
        investment.deletionReason = reason || 'Wrong package selected by user';
        investment.deletedAt = new Date();
        investment.deletedBy = req.user.email;
        await investment.save();

        const remainingInvestments = await Investment.find({
            userEmail: userEmail,
            status: { $in: ['Active', 'Completed'] },
            deleted: { $ne: true }
        });

        if (remainingInvestments.length > 0) {
            const newHighest = Math.max(...remainingInvestments.map(inv => inv.amount));
            await User.updateOne(
                { email: userEmail },
                { $set: { highestInvestmentAmount: newHighest } }
            );

            const lastInvestment = remainingInvestments.sort((a, b) => new Date(b.date) - new Date(a.date))[0];
            if (lastInvestment) {
                await User.updateOne(
                    { email: userEmail },
                    { $set: { lastInvestmentAmount: lastInvestment.amount } }
                );
            }
        } else {
            await User.updateOne(
                { email: userEmail },
                {
                    $set: {
                        highestInvestmentAmount: 0,
                        lastInvestmentAmount: 0
                    }
                }
            );
        }

        try {
            await resend.emails.send({
                from: `Premier Equation <${EMAIL_FROM}>`,
                to: [userEmail],
                subject: '🔄 Investment Reversed',
                html: `
                    <div style="font-family: Arial, sans-serif; color: #333;">
                        <h2>Investment Reversed</h2>
                        <p>Hello ${user.fullName},</p>
                        <p>Your investment in the <strong>${investment.package}</strong> package has been reversed by the administrator.</p>
                        <div style="background-color: #fff3cd; padding: 15px; border-left: 4px solid #ffc107; margin: 20px 0;">
                            <p><strong>Details:</strong></p>
                            <p>Amount: N${investment.amount.toLocaleString()}</p>
                            <p>Date: ${new Date(investment.date).toLocaleDateString()}</p>
                            <p>Reason: ${reason || 'Wrong package selection'}</p>
                        </div>
                        <p>${refundProcessed ?
                        'The funds have been refunded to your withdrawal balance.' :
                        'Please contact support for manual refund processing.'}</p>
                        <p>If you wish to reinvest, please select the correct package.</p>
                    </div>
                `
            });
        } catch (emailError) {
            console.error('Failed to send user notification:', emailError);
        }

        res.json({
            success: true,
            message: `Investment deleted successfully. ${refundProcessed ? 'Funds refunded to user wallet.' : 'Manual refund required.'}`
        });

    } catch (err) {
        console.error('Investment Deletion Error:', err);
        res.status(500).json({ success: false, message: 'Server error deleting investment' });
    }
});

app.get('/api/admin/users', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const users = await User.find({ isAdmin: false }).lean();

        const usersWithInvestments = await Promise.all(users.map(async (user) => {
            const activeInvestments = await Investment.find({
                userEmail: user.email,
                status: 'Active',
                deleted: { $ne: true }
            });

            return { ...user, activeInvestments };
        }));

        res.json(usersWithInvestments);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.post('/api/admin/user-action', authenticateToken, verifyAdmin, async (req, res) => {
    const { userEmail, action, amount, description, bankName, accountNumber } = req.body;

    try {
        let updateQuery = {};
        let transactionType = 'info';
        let txDescription = description;

        switch (action) {
            case 'credit':
                updateQuery = {
                    $inc: {
                        withdrawalBalance: Number(amount),
                        exemptWithdrawalBalance: Number(amount)
                    }
                };
                transactionType = 'credit';
                txDescription = description || "Admin Credit";
                break;
            case 'debit':
                updateQuery = { $inc: { withdrawalBalance: -Number(amount) } };
                transactionType = 'debit';
                txDescription = description || "Admin Debit";
                break;
            case 'suspend':
                updateQuery = { $set: { suspended: true } };
                break;
            case 'unsuspend':
                updateQuery = { $set: { suspended: false } };
                break;
            case 'edit-bank':
                updateQuery = { $set: { bankName, accountNumber } };
                break;
            case 'delete':
                await User.deleteOne({ email: userEmail });
                await Investment.deleteMany({ userEmail });
                await Transaction.deleteMany({ userEmail });
                await Withdrawal.deleteMany({ userEmail });
                await WalletRecommitment.deleteMany({ userEmail });
                return res.json({ success: true, message: "User Deleted" });
        }

        const result = await User.findOneAndUpdate({ email: userEmail }, updateQuery, { new: true });
        if (!result) return res.status(404).json({ error: "User not found" });

        if (action === 'debit' && result.exemptWithdrawalBalance > result.withdrawalBalance) {
            result.exemptWithdrawalBalance = result.withdrawalBalance;
            await result.save();
        }

        if (['credit', 'debit', 'suspend', 'unsuspend'].includes(action)) {
            await new Transaction({
                userEmail: userEmail,
                type: `Admin Action: ${action}`,
                amount: amount || 0,
                description: txDescription,
                transactionType: transactionType
            }).save();
        }

        res.json({ success: true });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.get('/api/admin/settings', authenticateToken, verifyAdmin, async (req, res) => {
    const settings = await Setting.findOne({ type: 'config' });
    res.json(settings);
});

app.post('/api/admin/settings', authenticateToken, verifyAdmin, async (req, res) => {
    const { packages, referralBonus, recommitment } = req.body;
    await Setting.findOneAndUpdate({ type: 'config' }, { packages, referralBonus, recommitment }, { upsert: true });
    res.json({ success: true });
});

app.post('/api/recommit/wallet', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;
        const { recommitmentAmount } = req.body;

        const user = await User.findOne({ email });
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found.' });
        }

        const settings = await Setting.findOne({ type: 'config' });
        const recommitmentEnabled = settings?.recommitment?.enabled ?? true;
        const recommitmentPercent = settings?.recommitment?.percentage ?? 50;

        if (!recommitmentEnabled) {
            return res.json({ success: true, message: "Recommitment policy is disabled." });
        }

        if (user.pendingRecommitmentAmount > 0) {
            return res.status(400).json({
                success: false,
                message: 'You already have a pending recommitment waiting for admin approval.'
            });
        }

        const allInvestments = await Investment.find({
            userEmail: email,
            status: { $in: ['Active', 'Completed', 'Settled'] },
            deleted: { $ne: true }
        });

        let highestInvestmentAmount = 0;
        let lastCompletedInvestment = null;

        if (allInvestments.length > 0) {
            highestInvestmentAmount = Math.max(...allInvestments.map(inv => inv.amount));

            const completed = allInvestments.filter(inv => inv.status === 'Completed' && !inv.withdrawn && !inv.isRecommitment);
            if (completed.length > 0) {
                completed.sort((a, b) => new Date(b.maturityDate) - new Date(a.maturityDate));
                lastCompletedInvestment = completed[0];
            } else {
                const anyValid = allInvestments.sort((a, b) => new Date(b.date) - new Date(a.date));
                lastCompletedInvestment = anyValid[0];
            }
        }

        if (!lastCompletedInvestment && allInvestments.length === 0) {
            return res.status(400).json({
                success: false,
                message: 'No eligible investment found requiring recommitment.'
            });
        }

        if (recommitmentAmount < highestInvestmentAmount) {
            return res.status(400).json({
                success: false,
                message: `Recommitment amount must be at least N${highestInvestmentAmount.toLocaleString()} (your highest previous investment).`
            });
        }

        const walletDeduction = recommitmentAmount * (recommitmentPercent / 100);

        if (user.withdrawalBalance < walletDeduction) {
            return res.status(400).json({
                success: false,
                message: `Insufficient wallet balance for ${recommitmentPercent}% deduction. Required: N${walletDeduction.toLocaleString()}, Available: N${user.withdrawalBalance.toLocaleString()}`
            });
        }

        user.withdrawalBalance -= walletDeduction;

        if (user.exemptWithdrawalBalance > user.withdrawalBalance) {
            user.exemptWithdrawalBalance = user.withdrawalBalance;
        }

        user.pendingRecommitmentAmount = recommitmentAmount;
        user.isEligibleForWithdrawal = false;
        await user.save();

        const newRecommitment = new WalletRecommitment({
            userEmail: email,
            originalInvestmentAmount: lastCompletedInvestment ? lastCompletedInvestment.amount : 0,
            recommitmentAmount: recommitmentAmount,
            walletDeduction: walletDeduction,
            originalInvestmentId: lastCompletedInvestment ? lastCompletedInvestment._id : null,
            status: 'Pending'
        });

        const savedRecommitment = await newRecommitment.save();

        const recommitmentInvestment = new Investment({
            userEmail: email,
            package: 'Wallet Recommitment',
            amount: recommitmentAmount,
            profit: 0,
            totalReturn: recommitmentAmount,
            returnRate: 0,
            duration: 0,
            proofImage: 'Wallet-Deduction',
            status: 'Pending',
            paymentMethod: 'Wallet',
            isRecommitment: true,
            originalInvestmentId: lastCompletedInvestment ? lastCompletedInvestment._id : null,
            walletDeduction: walletDeduction,
            isRecommitmentCycle: true,
            investmentCycle: 2
        });

        const savedInvestment = await recommitmentInvestment.save();

        savedRecommitment.recommitmentInvestmentId = savedInvestment._id;
        await savedRecommitment.save();

        await new Transaction({
            userEmail: email,
            type: 'Wallet Recommitment Deduction',
            amount: walletDeduction,
            description: `${recommitmentPercent}% wallet deduction for recommitment (Pending Admin Approval)`,
            transactionType: 'debit',
            status: 'Pending'
        }).save();

        res.json({
            success: true,
            message: `Wallet recommitment submitted! N${walletDeduction.toLocaleString()} (${recommitmentPercent}%) deducted from wallet. Balance to be settled at maturity. Waiting for admin approval.`,
            data: {
                walletDeduction: walletDeduction,
                newWalletBalance: user.withdrawalBalance,
                investmentId: savedInvestment._id
            }
        });

    } catch (error) {
        console.error('Wallet Recommitment Error:', error);
        res.status(500).json({ success: false, message: 'Server error processing wallet recommitment' });
    }
});

app.get('/api/recommit/eligibility', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;
        const user = await User.findOne({ email });

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

        const settings = await Setting.findOne({ type: 'config' });
        const recommitmentEnabled = settings?.recommitment?.enabled ?? true;
        const recommitmentPercent = settings?.recommitment?.percentage ?? 50;

        if (!recommitmentEnabled) {
            return res.json({ requiresRecommitment: false, isEligibleForWithdrawal: true });
        }

        if (user.pendingRecommitmentAmount > 0) {
            const pendingRecommitment = await WalletRecommitment.findOne({
                userEmail: email,
                status: 'Pending'
            });

            if (pendingRecommitment) {
                return res.json({
                    requiresRecommitment: true,
                    isEligibleForWithdrawal: false,
                    hasPendingRecommitment: true,
                    pendingAmount: user.pendingRecommitmentAmount,
                    lastInvestmentAmount: pendingRecommitment.originalInvestmentAmount,
                    walletDeduction: pendingRecommitment.walletDeduction,
                    percentage: recommitmentPercent
                });
            }
        }

        const allInvestments = await Investment.find({
            userEmail: email,
            status: { $in: ['Active', 'Completed', 'Settled'] },
            deleted: { $ne: true }
        });

        let highestInvestmentAmount = 0;
        let lastCompletedAmount = 0;
        let lastCompletedInvestment = null;

        if (allInvestments.length > 0) {
            highestInvestmentAmount = Math.max(...allInvestments.map(inv => inv.amount));

            const completed = allInvestments.filter(inv => inv.status === 'Completed' && !inv.withdrawn && !inv.isRecommitment);
            if (completed.length > 0) {
                completed.sort((a, b) => new Date(b.maturityDate) - new Date(a.maturityDate));
                lastCompletedInvestment = completed[0];
                lastCompletedAmount = lastCompletedInvestment.amount;
            }
        }

        if (!lastCompletedInvestment && allInvestments.length === 0) {
            return res.json({
                requiresRecommitment: false,
                isEligibleForWithdrawal: user.isEligibleForWithdrawal
            });
        }

        if (user.isEligibleForWithdrawal) {
            return res.json({
                requiresRecommitment: false,
                isEligibleForWithdrawal: true
            });
        }

        const minimumRequired = highestInvestmentAmount > 0 ? highestInvestmentAmount : lastCompletedAmount;

        const finalMin = minimumRequired || 0;

        res.json({
            requiresRecommitment: true,
            isEligibleForWithdrawal: false,
            lastInvestmentAmount: lastCompletedAmount,
            highestInvestmentAmount: highestInvestmentAmount,
            minimumRecommitment: finalMin,
            walletBalance: user.withdrawalBalance,
            requiredDeduction: finalMin * (recommitmentPercent / 100),
            percentage: recommitmentPercent
        });

    } catch (error) {
        res.status(500).json({ error: 'Server error checking recommitment eligibility' });
    }
});

app.get('/api/admin/recommitments/pending', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const pendingRecommitments = await WalletRecommitment.find({ status: 'Pending' })
            .populate('recommitmentInvestmentId')
            .sort({ date: -1 });

        const recommitmentsWithUser = await Promise.all(pendingRecommitments.map(async (rec) => {
            const user = await User.findOne({ email: rec.userEmail });
            const originalInvestment = await Investment.findById(rec.originalInvestmentId);
            return {
                ...rec.toObject(),
                user: {
                    fullName: user?.fullName || 'Unknown',
                    email: user?.email,
                    walletBalance: user?.withdrawalBalance || 0
                },
                originalInvestment: originalInvestment
            };
        }));

        res.json(recommitmentsWithUser);
    } catch (error) {
        res.status(500).json({ error: 'Failed to fetch pending recommitments' });
    }
});

app.post('/api/admin/recommitments/action', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const { recommitmentId, action } = req.body;

        const recommitment = await WalletRecommitment.findById(recommitmentId);
        if (!recommitment || recommitment.status !== 'Pending') {
            return res.status(400).json({ success: false, message: 'Recommitment not found or already processed' });
        }

        const user = await User.findOne({ email: recommitment.userEmail });
        if (!user) {
            return res.status(404).json({ success: false, message: 'User not found' });
        }

        const investment = await Investment.findById(recommitment.recommitmentInvestmentId);
        if (!investment) {
            return res.status(404).json({ success: false, message: 'Investment not found' });
        }

        if (action === 'approve') {
            recommitment.status = 'Approved';
            recommitment.approvedAt = new Date();
            recommitment.approvedBy = req.user.email;
            await recommitment.save();

            investment.status = 'Active';
            await investment.save();

            user.isEligibleForWithdrawal = true;
            user.pendingRecommitmentAmount = 0;
            await user.save();

            await Transaction.updateMany(
                {
                    userEmail: recommitment.userEmail,
                    amount: recommitment.walletDeduction,
                    type: 'Wallet Recommitment Deduction',
                    status: 'Pending'
                },
                { status: 'Completed' }
            );

            res.json({ success: true, message: 'Recommitment approved successfully' });

        } else if (action === 'reject') {
            recommitment.status = 'Rejected';
            await recommitment.save();

            user.withdrawalBalance += recommitment.walletDeduction;
            if (user.exemptWithdrawalBalance > user.withdrawalBalance) {
                user.exemptWithdrawalBalance = user.withdrawalBalance;
            }
            user.pendingRecommitmentAmount = 0;
            await user.save();

            investment.status = 'Rejected';
            await investment.save();

            await new Transaction({
                userEmail: recommitment.userEmail,
                type: 'Recommitment Refund',
                amount: recommitment.walletDeduction,
                description: 'Refund for rejected wallet recommitment',
                transactionType: 'credit',
                status: 'Completed'
            }).save();

            await Transaction.updateMany(
                {
                    userEmail: recommitment.userEmail,
                    amount: recommitment.walletDeduction,
                    type: 'Wallet Recommitment Deduction',
                    status: 'Pending'
                },
                { status: 'Failed' }
            );

            res.json({ success: true, message: 'Recommitment rejected and funds refunded' });
        }
    } catch (error) {
        console.error('Recommitment Action Error:', error);
        res.status(500).json({ success: false, message: 'Server error processing recommitment' });
    }
});

async function processCycleMaturity(investment) {
    try {
        const user = await User.findOne({ email: investment.userEmail });
        if (!user) return false;

        if (investment.isRecommitmentCycle && investment.investmentCycle >= 2) {

            investment.status = 'Settlement Required';
            investment.settlementAmount = investment.amount;
            investment.cycleSettlementRequired = true;

            investment.remainingRecommitmentBalance = investment.amount * 0.5;

            investment.nextCycleRecommitment = investment.amount * 0.5;

            if (!investment.originalRecommitmentAmount || investment.originalRecommitmentAmount === 0) {
                investment.originalRecommitmentAmount = investment.amount;
            }

            await investment.save();

            await User.updateOne(
                { email: investment.userEmail },
                { $set: { cycleSettlementRequired: true } }
            );

            try {
                await resend.emails.send({
                    from: `Premier Equation <${EMAIL_FROM}>`,
                    to: [user.email],
                    subject: `🔄 Cycle ${investment.investmentCycle} Settlement Required`,
                    html: `
                        <div style="font-family: Arial, sans-serif; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px;">
                            <h2 style="color: #004d40; text-align: center;">Cycle ${investment.investmentCycle} Settlement Required</h2>
                            <p>Hello ${user.fullName},</p>
                            <p>Your investment in the <strong>${investment.package}</strong> package (Cycle ${investment.investmentCycle}) has matured and requires settlement.</p>
                            
                            <div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0;">
                                <p style="margin: 5px 0;"><strong>Investment Details:</strong></p>
                                <p style="margin: 5px 0;">Cycle: ${investment.investmentCycle}</p>
                                <p style="margin: 5px 0;">Original Amount: N${investment.amount.toLocaleString()}</p>
                                <p style="margin: 5px 0;">Total Return: <span style="color: #28a745; font-weight: bold;">N${investment.totalReturn.toLocaleString()}</span></p>
                                <p style="margin: 5px 0;"><strong>Settlement Required: N${investment.settlementAmount.toLocaleString()}</strong></p>
                            </div>
                            
                            <h3 style="color: #004d40; margin-top: 25px;">Settlement Breakdown:</h3>
                            <ul style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 15px 0;">
                                <li><strong>N${investment.remainingRecommitmentBalance.toLocaleString()}</strong> completes the remaining 50% balance for Cycle ${investment.investmentCycle}</li>
                                <li><strong>N${investment.nextCycleRecommitment.toLocaleString()}</strong> will be registered as new recommitment for Cycle ${investment.investmentCycle + 1}</li>
                            </ul>
                            
                            <p>To withdraw your returns of <strong>N${investment.totalReturn.toLocaleString()}</strong>, you must complete the 100% settlement payment.</p>
                            
                            <div style="text-align: center; margin-top: 30px;">
                                <a href="#" style="background-color: #004d40; color: white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-weight: bold;">Complete Settlement</a>
                            </div>
                            
                            <p style="margin-top: 30px; font-size: 12px; color: #888; text-align: center;">This settlement is required for all Cycle 2+ investments.</p>
                        </div>
                    `
                });
            } catch (emailError) {
                console.error('Failed to send cycle settlement email:', emailError.message);
            }

            return false;
        }

        return true;
    } catch (error) {
        console.error('Cycle maturity processing error:', error);
        return true;
    }
}

app.get('/api/cycle/settlement/requirements', authenticateToken, async (req, res) => {
    try {
        const email = req.user.email;

        const settlementRequired = await Investment.find({
            userEmail: email,
            status: 'Settlement Required',
            isRecommitmentCycle: true,
            investmentCycle: { $gte: 2 }
        }).sort({ investmentCycle: 1 });

        if (settlementRequired.length === 0) {
            return res.json({ requiresSettlement: false });
        }

        const requirements = settlementRequired.map(inv => ({
            investmentId: inv._id,
            cycle: inv.investmentCycle,
            package: inv.package,
            amount: inv.amount,
            settlementAmount: inv.settlementAmount || inv.amount,
            remainingBalance: inv.remainingRecommitmentBalance || (inv.amount * 0.5),
            nextCycleAmount: inv.nextCycleRecommitment || (inv.amount * 0.5),
            totalReturn: inv.totalReturn,
            maturityDate: inv.maturityDate
        }));

        res.json({
            requiresSettlement: true,
            requirements: requirements
        });

    } catch (error) {
        console.error('Error checking settlement requirements:', error);
        res.status(500).json({ error: 'Server error checking settlement requirements' });
    }
});

app.post('/api/cycle/settlement', authenticateToken, async (req, res) => {
    try {
        const { investmentId, paymentMethod, proofImage } = req.body;
        const email = req.user.email;

        const investment = await Investment.findOne({
            _id: investmentId,
            userEmail: email,
            status: 'Settlement Required',
            isRecommitmentCycle: true,
            investmentCycle: { $gte: 2 }
        });

        if (!investment) {
            return res.status(400).json({
                success: false,
                message: 'Settlement not required or investment not found'
            });
        }

        const user = await User.findOne({ email });
        const settlementAmount = investment.settlementAmount || investment.amount;

        if (paymentMethod === 'wallet') {
            if (user.withdrawalBalance < settlementAmount) {
                return res.status(400).json({
                    success: false,
                    message: 'Insufficient wallet balance for settlement'
                });
            }

            await User.updateOne(
                { email },
                { $inc: { withdrawalBalance: -settlementAmount } }
            );

            const updatedUser = await User.findOne({ email });
            if (updatedUser.exemptWithdrawalBalance > updatedUser.withdrawalBalance) {
                updatedUser.exemptWithdrawalBalance = updatedUser.withdrawalBalance;
                await updatedUser.save();
            }

        } else {
            if (!proofImage) {
                return res.status(400).json({
                    success: false,
                    message: 'Payment proof required for manual settlement'
                });
            }

            let proofUrl = '';
            try {
                proofUrl = await uploadProof(proofImage);
            } catch (uploadError) {
                return res.status(500).json({
                    error: 'Image upload failed: ' + uploadError.message
                });
            }

            investment.proofImage = proofUrl;
        }

        investment.cycle2SettlementPaid = true;
        investment.totalPaidForCycle = investment.amount;
        investment.status = 'Settlement Pending';
        investment.settlementDate = new Date();
        investment.paymentMethod = paymentMethod === 'wallet' ? 'Wallet' : 'Manual';

        await investment.save();

        await new Transaction({
            userEmail: email,
            type: 'Cycle Settlement Payment',
            amount: settlementAmount,
            description: `Cycle ${investment.investmentCycle} settlement - 100% payment`,
            transactionType: 'debit',
            status: 'Pending'
        }).save();

        const nextCycleNumber = investment.investmentCycle + 1;

        const nextCyclePrincipalAmount = investment.amount;

        const nextCyclePartialPayment = investment.nextCycleRecommitment || (investment.amount * 0.5);

        const nextCycleInvestment = new Investment({
            userEmail: email,
            package: investment.package,
            amount: nextCyclePrincipalAmount,
            profit: nextCyclePrincipalAmount * (investment.returnRate / 100),
            totalReturn: nextCyclePrincipalAmount + (nextCyclePrincipalAmount * (investment.returnRate / 100)),
            returnRate: investment.returnRate,
            duration: investment.duration,
            investmentCycle: nextCycleNumber,
            isRecommitmentCycle: true,
            originalInvestmentId: investment._id,
            status: 'Pending',
            paymentMethod: 'System Generated',
            proofImage: 'Cycle Continuation',
            walletDeduction: nextCyclePartialPayment,
            originalRecommitmentAmount: investment.originalRecommitmentAmount || investment.amount
        });

        await nextCycleInvestment.save();

        res.json({
            success: true,
            message: `Cycle ${investment.investmentCycle} settlement submitted. N${nextCyclePrincipalAmount.toLocaleString()} registered for Cycle ${nextCycleNumber}.`,
            data: {
                currentCycle: investment.investmentCycle,
                nextCycle: nextCycleNumber,
                nextCycleAmount: nextCyclePrincipalAmount
            }
        });

    } catch (error) {
        console.error('Cycle settlement error:', error);
        res.status(500).json({ success: false, message: 'Server error processing settlement' });
    }
});

app.get('/api/admin/cycle/settlements/pending', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const settlements = await Investment.find({
            status: 'Settlement Pending',
            isRecommitmentCycle: true,
            investmentCycle: { $gte: 2 }
        }).sort({ investmentCycle: 1 });

        res.json(settlements);
    } catch (error) {
        console.error('Error fetching cycle settlements:', error);
        res.status(500).json({ error: 'Failed to fetch cycle settlements' });
    }
});

app.post('/api/admin/cycle/settlement/approve', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const { investmentId } = req.body;

        const investment = await Investment.findOne({
            _id: investmentId,
            status: 'Settlement Pending',
            isRecommitmentCycle: true
        });

        if (!investment) {
            return res.status(400).json({
                success: false,
                message: 'Pending settlement not found'
            });
        }

        investment.status = 'Settled';
        investment.settlementApprovedAt = new Date();
        investment.settlementApprovedBy = req.user.email;
        await investment.save();

        const user = await User.findOne({ email: investment.userEmail });
        if (user) {
            await User.updateOne(
                { email: investment.userEmail },
                {
                    $inc: { withdrawalBalance: investment.totalReturn },
                    $set: {
                        isEligibleForWithdrawal: true,
                        cycleSettlementRequired: false
                    }
                }
            );

            await new Transaction({
                userEmail: investment.userEmail,
                type: 'Cycle Returns Release',
                amount: investment.totalReturn,
                description: `Cycle ${investment.investmentCycle} returns released after settlement`,
                transactionType: 'credit',
                status: 'Completed'
            }).save();
        }

        await Transaction.updateMany(
            {
                userEmail: investment.userEmail,
                type: 'Cycle Settlement Payment',
                amount: investment.settlementAmount || investment.amount,
                status: 'Pending'
            },
            { status: 'Completed' }
        );

        const nextCycleInvestment = await Investment.findOne({
            userEmail: investment.userEmail,
            originalInvestmentId: investment._id,
            status: 'Pending'
        });

        if (nextCycleInvestment) {
            nextCycleInvestment.status = 'Active';
            const startDate = new Date();
            const maturityDate = new Date();
            maturityDate.setDate(startDate.getDate() + nextCycleInvestment.duration);
            nextCycleInvestment.date = startDate;
            nextCycleInvestment.maturityDate = maturityDate;
            await nextCycleInvestment.save();

            await new Transaction({
                userEmail: investment.userEmail,
                type: 'Cycle Investment',
                amount: nextCycleInvestment.amount,
                description: `Cycle ${nextCycleInvestment.investmentCycle} investment approved (Auto-generated)`,
                transactionType: 'debit',
                status: 'Completed'
            }).save();
        }

        res.json({
            success: true,
            message: `Cycle ${investment.investmentCycle} settlement approved. Returns released to user and Cycle ${investment.investmentCycle + 1} investment activated.`
        });

    } catch (error) {
        console.error('Settlement approval error:', error);
        res.status(500).json({ success: false, message: 'Server error approving settlement' });
    }
});

app.post('/api/admin/cycle/settlement/reject', authenticateToken, verifyAdmin, async (req, res) => {
    try {
        const { investmentId, reason } = req.body;

        const investment = await Investment.findOne({
            _id: investmentId,
            status: 'Settlement Pending',
            isRecommitmentCycle: true
        });

        if (!investment) {
            return res.status(400).json({ success: false, message: 'Pending settlement not found' });
        }

        if (investment.paymentMethod === 'Wallet') {
            const settlementAmount = investment.settlementAmount || investment.amount;
            await User.updateOne(
                { email: investment.userEmail },
                { $inc: { withdrawalBalance: settlementAmount } }
            );

            const user = await User.findOne({ email: investment.userEmail });
            if (user.exemptWithdrawalBalance > user.withdrawalBalance) {
                user.exemptWithdrawalBalance = user.withdrawalBalance;
                await user.save();
            }

            await new Transaction({
                userEmail: investment.userEmail,
                type: 'Settlement Refund',
                amount: settlementAmount,
                description: `Refund for rejected cycle settlement`,
                transactionType: 'credit',
                status: 'Completed'
            }).save();
        }

        await Transaction.updateMany(
            {
                userEmail: investment.userEmail,
                type: 'Cycle Settlement Payment',
                amount: investment.settlementAmount || investment.amount,
                status: 'Pending'
            },
            { status: 'Failed', description: 'Cycle settlement rejected' }
        );

        await Investment.deleteOne({
            userEmail: investment.userEmail,
            originalInvestmentId: investment._id,
            status: 'Pending',
            isRecommitmentCycle: true
        });

        investment.status = 'Settlement Required';
        investment.cycle2SettlementPaid = false;
        investment.totalPaidForCycle = 0;
        investment.paymentMethod = 'Manual';
        investment.proofImage = '';
        await investment.save();

        res.json({ success: true, message: 'Settlement rejected. User can now re-submit.' });

    } catch (error) {
        console.error('Settlement rejection error:', error);
        res.status(500).json({ success: false, message: 'Server error rejecting settlement' });
    }
});

setInterval(async () => {
    try {
        const now = new Date();
        const candidates = await Investment.find({
            status: 'Active',
            maturityDate: { $lte: now },
            deleted: { $ne: true }
        });

        if (candidates.length > 0) {
            console.log(`[Auto-Maturity] Found ${candidates.length} investments to process...`);

            for (const candidate of candidates) {
                const isCycle2Plus = candidate.isRecommitmentCycle && candidate.investmentCycle >= 2;

                if (isCycle2Plus) {
                    const shouldCredit = await processCycleMaturity(candidate);

                    if (!shouldCredit) {
                        console.log(`[Cycle ${candidate.investmentCycle}] Settlement required before crediting returns`);
                        continue;
                    }
                }

                const inv = await Investment.findOneAndUpdate(
                    { _id: candidate._id, status: 'Active', deleted: { $ne: true } },
                    { $set: { status: 'Completed' } },
                    { new: true }
                );

                if (inv) {
                    await User.updateOne(
                        { email: inv.userEmail },
                        { $inc: { withdrawalBalance: inv.totalReturn } }
                    );

                    await new Transaction({
                        userEmail: inv.userEmail,
                        type: 'Investment Maturity',
                        amount: inv.totalReturn,
                        description: `Maturity return for ${inv.package} package (Cycle ${inv.investmentCycle})`,
                        transactionType: 'credit',
                        status: 'Completed'
                    }).save();

                    console.log(`[Auto-Maturity] Credited ${inv.userEmail} with N${inv.totalReturn}`);

                    try {
                        await resend.emails.send({
                            from: `Premier Equation <${EMAIL_FROM}>`,
                            to: [inv.userEmail],
                            subject: '🎉 Investment Matured!',
                            html: `
                                <div style="font-family: Arial, sans-serif; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px;">
                                    <h2 style="color: #004d40; text-align: center;">Investment Completed</h2>
                                    <p>Hello,</p>
                                    <p>Congratulations! Your investment in the <strong>${inv.package}</strong> package has successfully matured.</p>

                                    <div style="background-color: #f4fdf4; border-left: 4px solid #28a745; padding: 15px; margin: 20px 0;">
                                        <p style="margin: 5px 0;"><strong>Amount Credited:</strong> <span style="font-size: 1.2em; color: #28a745;">N${inv.totalReturn.toLocaleString()}</span></p>
                                        <p style="margin: 5px 0;"><strong>Package:</strong> ${inv.package}</p>
                                        <p style="margin: 5px 0;"><strong>Cycle:</strong> ${inv.investmentCycle}</p>
                                        <p style="margin: 5px 0;"><strong>Date:</strong> ${new Date().toLocaleDateString()}</p>
                                    </div>

                                    <p>The funds have been added to your <strong>Withdrawal Balance</strong>. You can withdraw them immediately or reinvest to earn more.</p>

                                    <div style="text-align: center; margin-top: 30px;">
                                        <a href="#" style="background-color: #004d40; color: white; padding: 12px 25px; text-decoration: none; border-radius: 5px; font-weight: bold;">Go to Dashboard</a>
                                    </div>

                                    <p style="margin-top: 30px; font-size: 12px; color: #888; text-align: center;">Thank you for choosing Premier Equation.</p>
                                </div>
                            `
                        });
                        console.log(`[Auto-Maturity] Email sent to ${inv.userEmail}`);
                    } catch (emailError) {
                        console.error(`[Auto-Maturity] Failed to send email to ${inv.userEmail}:`, emailError.message);
                    }
                }
            }
        }
    } catch (err) {
        console.error('[Auto-Maturity] Critical Error processing investments:', err);
    }
}, 300000);

app.get(/.*/, (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});