const nocodbService = require('../services/nocodb');
const logger = require('../utils/logger');
const config = require('../config');
const { sanitizeUser, extractId } = require('../utils/helpers');
const { sendLoginDetails } = require('../services/email');
const listmonkService = require('../services/listmonk');

class UsersController {
    async getAll(req, res) {
        try {
            // Debug logging
            logger.info('UsersController.getAll called');
            logger.info('loginSheetId from config:', config.nocodb.loginSheetId);
            logger.info('NocoDB config:', {
                apiUrl: config.nocodb.apiUrl,
                hasToken: !!config.nocodb.apiToken,
                projectId: config.nocodb.projectId,
                tableId: config.nocodb.tableId,
                loginSheetId: config.nocodb.loginSheetId
            });
            
            if (!config.nocodb.loginSheetId) {
                logger.error('Login sheet not configured in environment');
                return res.status(500).json({
                    success: false,
                    error: 'Login sheet not configured. Please set NOCODB_LOGIN_SHEET in your environment variables.'
                });
            }
            
            logger.info('Fetching users from NocoDB...');
            // Remove the sort parameter that's causing the error
            const response = await nocodbService.getAll(config.nocodb.loginSheetId, {
                limit: 100
                // Removed: sort: '-created_at'
            });
            
            const users = response.list || [];
            logger.info(`Retrieved ${users.length} users from database`);
            
            // Remove password field from response for security
            const safeUsers = users.map(sanitizeUser);
            
            res.json({
                success: true,
                users: safeUsers
            });
            
        } catch (error) {
            logger.error('Error fetching users:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to fetch users: ' + error.message
            });
        }
    }
    
    async create(req, res) {
        try {
            const { email, password, name, phone, isAdmin, userType, expireDays } = req.body;
            
            if (!email || !password) {
                return res.status(400).json({
                    success: false,
                    error: 'Email and password are required'
                });
            }
            
            if (!config.nocodb.loginSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Login sheet not configured'
                });
            }
            
            // Check if user already exists
            const existingUser = await nocodbService.getUserByEmail(email);
            
            if (existingUser) {
                return res.status(400).json({
                    success: false,
                    error: 'User with this email already exists'
                });
            }
            
            // Calculate expiration date for temp users
            let expiresAt = null;
            if (userType === 'temp' && expireDays) {
                const expirationDate = new Date();
                expirationDate.setDate(expirationDate.getDate() + expireDays);
                expiresAt = expirationDate.toISOString();
            }
            
            // Create new user - use the actual column names from your table
            const userData = {
                Email: email,
                email: email,
                Password: password,
                password: password,
                Name: name || '',
                name: name || '',
                Phone: phone || '',
                phone: phone || '',
                Admin: isAdmin === true,
                admin: isAdmin === true,
                'User Type': userType || 'user', // Handle space in field name
                UserType: userType || 'user',
                userType: userType || 'user',
                CreatedAt: new Date().toISOString(),
                ExpiresAt: expiresAt,
                ExpireDays: userType === 'temp' ? expireDays : null
            };
            
            const response = await nocodbService.create(
                config.nocodb.loginSheetId,
                userData
            );
            
            // Real-time sync to Listmonk (async, don't block response)
            if (listmonkService.syncEnabled && email) {
                setImmediate(async () => {
                    try {
                        const userForSync = {
                            ID: extractId(response),
                            Email: email,
                            Name: name,
                            Phone: phone,
                            Admin: isAdmin,
                            'User Type': userType, // Handle space in field name
                            UserType: userType,
                            'Created At': new Date().toISOString(),
                            ExpiresAt: expiresAt
                        };
                        
                        const syncResult = await listmonkService.syncUser(userForSync);
                        if (!syncResult.success) {
                            logger.warn('Listmonk sync failed for new user', {
                                userId: extractId(response),
                                email: email,
                                error: syncResult.error
                            });
                        } else {
                            logger.debug('User synced to Listmonk', {
                                userId: extractId(response),
                                email: email
                            });
                        }
                    } catch (error) {
                        logger.error('Listmonk sync error for new user', {
                            email: email,
                            error: error.message
                        });
                    }
                });
            }
            
            res.status(201).json({
                success: true,
                message: 'User created successfully',
                user: {
                    id: extractId(response),
                    email: email,
                    name: name,
                    phone: phone,
                    admin: isAdmin,
                    userType: userType,
                    expiresAt: expiresAt
                }
            });
            
        } catch (error) {
            logger.error('Error creating user:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to create user'
            });
        }
    }
    
    async delete(req, res) {
        try {
            const userId = req.params.id;
            
            if (!config.nocodb.loginSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Login sheet not configured'
                });
            }
            
            // Don't allow admins to delete themselves
            if (userId === req.session.userId) {
                return res.status(400).json({
                    success: false,
                    error: 'Cannot delete your own account'
                });
            }
            
            // Get user data before deletion (for Listmonk cleanup)
            let userData = null;
            if (listmonkService.syncEnabled) {
                try {
                    const getResponse = await nocodbService.getById(config.nocodb.loginSheetId, userId);
                    userData = getResponse;
                } catch (error) {
                    logger.warn('Could not fetch user data before deletion', error.message);
                }
            }
            
            await nocodbService.delete(
                config.nocodb.loginSheetId,
                userId
            );
            
            // Remove from Listmonk (async, don't block response)
            if (listmonkService.syncEnabled && userData && userData.Email) {
                setImmediate(async () => {
                    try {
                        const syncResult = await listmonkService.syncUser(userData, 'delete');
                        if (!syncResult.success) {
                            logger.warn('Failed to remove deleted user from Listmonk', {
                                userId: userId,
                                email: userData.Email,
                                error: syncResult.error
                            });
                        } else {
                            logger.debug('Deleted user removed from Listmonk', {
                                userId: userId,
                                email: userData.Email
                            });
                        }
                    } catch (error) {
                        logger.error('Listmonk cleanup error for deleted user', {
                            userId: userId,
                            error: error.message
                        });
                    }
                });
            }
            
            res.json({
                success: true,
                message: 'User deleted successfully'
            });
            
        } catch (error) {
            logger.error('Error deleting user:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to delete user'
            });
        }
    }
    
    async sendLoginDetails(req, res) {
        try {
            const userId = req.params.id;
            
            if (!config.nocodb.loginSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Login sheet not configured'
                });
            }
            
            // Get user data from database
            const user = await nocodbService.getById(
                config.nocodb.loginSheetId,
                userId
            );
            
            if (!user) {
                return res.status(404).json({
                    success: false,
                    error: 'User not found'
                });
            }
            
            // Send login details email
            await sendLoginDetails(user);
            
            res.json({
                success: true,
                message: 'Login details sent successfully'
            });
            
        } catch (error) {
            logger.error('Error sending login details:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to send login details'
            });
        }
    }

    async emailAllUsers(req, res) {
        try {
            const { subject, content } = req.body;
            
            if (!subject || !content) {
                return res.status(400).json({
                    success: false,
                    error: 'Subject and content are required'
                });
            }

            if (!config.nocodb.loginSheetId) {
                return res.status(500).json({
                    success: false,
                    error: 'Login sheet not configured'
                });
            }

            // Get all users
            const response = await nocodbService.getAll(config.nocodb.loginSheetId, {
                limit: 1000
            });
            
            const users = response.list || [];
            
            if (users.length === 0) {
                return res.status(400).json({
                    success: false,
                    error: 'No users found to email'
                });
            }

            // Import email service
            const { sendEmail } = require('../services/email');
            const emailTemplates = require('../services/emailTemplates');
            const config_app = require('../config');

            // Convert rich text content to plain text for the text version
            const stripHtmlTags = (html) => {
                return html.replace(/<[^>]*>/g, '').replace(/\s+/g, ' ').trim();
            };

            // Prepare base template variables
            const baseTemplateVariables = {
                APP_NAME: 'CMlite Map - User Broadcast',
                EMAIL_SUBJECT: subject,
                EMAIL_CONTENT: content,
                EMAIL_CONTENT_TEXT: stripHtmlTags(content),
                SENDER_NAME: req.session.userName || req.session.userEmail || 'Administrator',
                TIMESTAMP: new Date().toLocaleString()
            };

            // Send emails to all users
            const emailResults = [];
            const failedEmails = [];

            for (const user of users) {
                try {
                    const userVariables = {
                        ...baseTemplateVariables,
                        USER_NAME: user.Name || user.name || user.Email || user.email || 'User',
                        USER_EMAIL: user.Email || user.email
                    };

                    const emailContent = await emailTemplates.render('user-broadcast', userVariables);
                    
                    await sendEmail({
                        to: user.Email || user.email,
                        subject: subject,
                        text: emailContent.text,
                        html: emailContent.html
                    });

                    emailResults.push({
                        email: user.Email || user.email,
                        name: user.Name || user.name || user.Email || user.email,
                        success: true
                    });

                    logger.info(`Sent broadcast email to: ${user.Email || user.email}`);
                } catch (emailError) {
                    logger.error(`Failed to send broadcast email to ${user.Email || user.email}:`, emailError);
                    failedEmails.push({
                        email: user.Email || user.email,
                        name: user.Name || user.name || user.Email || user.email,
                        error: emailError.message
                    });
                }
            }

            const successCount = emailResults.length;
            const failCount = failedEmails.length;

            if (successCount === 0) {
                return res.status(500).json({
                    success: false,
                    error: 'Failed to send any emails',
                    details: failedEmails
                });
            }

            res.json({
                success: true,
                message: `Sent email to ${successCount} user${successCount !== 1 ? 's' : ''}${failCount > 0 ? `, ${failCount} failed` : ''}`,
                results: {
                    successful: emailResults,
                    failed: failedEmails,
                    total: users.length,
                    subject: subject
                }
            });

        } catch (error) {
            logger.error('Error sending broadcast email:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to send broadcast email'
            });
        }
    }
}

module.exports = new UsersController();