const User = require('../models/User');
const Client = require('../models/Client');
const bcrypt = require('bcryptjs');

const userController = {
    // Change password for authenticated user
    changeMyPassword: (req, res) => {
        const userId = req.user?.id;
        const { current_password, new_password } = req.body || {};

        if (!userId) {
            return res.status(401).json({ error: 'Unauthorized. User context missing.' });
        }

        if (!current_password || !new_password) {
            return res.status(400).json({ error: 'current_password and new_password are required' });
        }

        if (current_password === new_password) {
            return res.status(400).json({ error: 'New password must be different from current password' });
        }

        User.findById(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }

            const user = results[0];
            
            // Compare current password with hashed password
            bcrypt.compare(current_password, user.password, (err, isMatch) => {
                if (err) {
                    return res.status(500).json({ error: 'Error comparing password' });
                }
                
                if (!isMatch) {
                    return res.status(403).json({ error: 'Current password is incorrect' });
                }

                // Hash the new password before updating
                bcrypt.hash(new_password, 10, (hashErr, hashedPassword) => {
                    if (hashErr) {
                        return res.status(500).json({ error: 'Error hashing new password' });
                    }

                    User.update(userId, { password: hashedPassword }, (updateErr, updateResults) => {
                if (updateErr) {
                    return res.status(500).json({ error: updateErr.message });
                }
                        if (updateResults.affectedRows === 0) {
                            return res.status(404).json({ message: 'User not found' });
                        }

                        return res.json({ message: 'Password updated successfully' });
                    });
                });
            });
        });
    },

    // Get all users
    getAll: (req, res) => {
        User.findAll((err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            res.json(results);
        });
    },

    // Get user by ID
    getById: (req, res) => {
        const userId = req.params.id;
        User.findById(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }
            // Don't return password in response
            const user = results[0];
            delete user.password;
            delete user.OTP;
            res.json(user);
        });
    },

    // Create new user (admin function - without OTP verification)
    create: (req, res) => {
        const { first_name, last_name, email, password, role, is_verified } = req.body;
        
        if (!first_name || !last_name || !email || !password || !role) {
            return res.status(400).json({ 
                error: 'Missing required fields: first_name, last_name, email, password, and role are required' 
            });
        }

        // Check if email already exists
        User.findByEmail(email, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            
            if (results.length > 0) {
                return res.status(400).json({ error: 'Email already registered' });
            }

            // Hash the password before creating user
            bcrypt.hash(password, 10, (err, hashedPassword) => {
                if (err) {
                    return res.status(500).json({ error: 'Error hashing password' });
                }

                // Create user without OTP (admin-created users can be pre-verified)
                // Auto-verify drivers and admins
                const roleLower = role?.toLowerCase();
                const shouldAutoVerify = roleLower === 'driver' || roleLower === 'admin';
                const verifiedStatus = shouldAutoVerify ? true : (is_verified !== undefined ? is_verified : false);
                User.create({
                    first_name,
                    last_name,
                    email,
                    password: hashedPassword,
                    role,
                    otp: null,
                    is_verified: verifiedStatus
                }, (err, userResults) => {
                if (err) {
                    if (err.code === 'ER_DUP_ENTRY') {
                        return res.status(400).json({ error: 'Email already exists' });
                    }
                    return res.status(500).json({ error: err.message });
                }

                    const userId = userResults.insertId;
                    
                    // Return user data without password
                    User.findById(userId, (err, newUser) => {
                        if (err) {
                            return res.status(500).json({ error: err.message });
                        }
                        const user = newUser[0];
                        delete user.password;
                        delete user.OTP;
                        
                        res.status(201).json({
                            message: 'User created successfully',
                            user: user
                        });
                    });
                });
            });
        });
    },

    // Update user (admin only, cannot update email, id, or role)
    update: (req, res) => {
        const userId = req.params.id;
        const { first_name, last_name, email, password, role, is_verified } = req.body;

        // Prevent editing of email, id, and role
        if (email !== undefined) {
            return res.status(400).json({ 
                error: 'Email cannot be updated',
                message: 'Email, id, and role fields are not editable.'
            });
        }
        if (role !== undefined) {
            return res.status(400).json({ 
                error: 'Role cannot be updated',
                message: 'Email, id, and role fields are not editable.'
            });
        }

        // Check if user exists
        User.findById(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }

            // If password is being updated, hash it first
            const updateData = {
                first_name,
                last_name,
                is_verified
            };

            // Hash password if provided
            if (password !== undefined) {
                bcrypt.hash(password, 10, (err, hashedPassword) => {
                    if (err) {
                        return res.status(500).json({ error: 'Error hashing password' });
                    }
                    
                    updateData.password = hashedPassword;
                    proceedWithUpdate();
                });
            } else {
                proceedWithUpdate();
            }

            function proceedWithUpdate() {
                // Proceed with update (only first_name, last_name, password, and is_verified can be updated)
                User.update(userId, updateData, (err, updateResults) => {
                    if (err) {
                        return res.status(500).json({ error: err.message });
                    }
                    
                    // Return updated user data
                    User.findById(userId, (err, updatedUser) => {
                        if (err) {
                            return res.status(500).json({ error: err.message });
                        }
                        const user = updatedUser[0];
                        delete user.password;
                        delete user.OTP;
                        
                        res.json({
                            message: 'User updated successfully',
                            user: user
                        });
                    });
                });
            }
        });
    },

    // Delete user
    delete: (req, res) => {
        const userId = req.params.id;
        
        // Check if user exists
        User.findById(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }

            User.delete(userId, (err, deleteResults) => {
                if (err) {
                    return res.status(500).json({ error: err.message });
                }
                res.json({ message: 'User deleted successfully' });
            });
        });
    },

    // Get user with all ambulance requests
    getByIdWithRequests: (req, res) => {
        const userId = req.params.id;
        User.findByIdWithRequests(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ message: 'User not found' });
            }
            
            const userData = results[0];
            // Parse JSON requests if it's a string, otherwise use as is
            if (typeof userData.requests === 'string') {
                try {
                    userData.requests = JSON.parse(userData.requests);
                } catch (e) {
                    userData.requests = [];
                }
            }
            // Remove password and OTP if they exist
            delete userData.password;
            delete userData.OTP;
            
            res.json(userData);
        });
    },

    // Get all clients with user data
    getAllClients: (req, res) => {
        Client.findAllWithUsers((err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            res.json(results);
        });
    }
};

module.exports = userController;

