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

class UsersController {
    async getAll(req, res) {
        try {
            console.log('UsersController.getAll called');
            console.log('Users table ID:', nocodbService.tableIds.users);

            if (!nocodbService.tableIds.users) {
                console.error('Users table not configured in environment');
                return res.status(500).json({
                    success: false,
                    error: 'Users table not configured. Please set NOCODB_TABLE_USERS in your environment variables.'
                });
            }

            console.log('Fetching users from NocoDB...');
            const response = await nocodbService.getAll(nocodbService.tableIds.users, {
                limit: 100
            });

            const users = response.list || [];
            console.log(`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) {
            console.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 (!nocodbService.tableIds.users) {
                return res.status(500).json({
                    success: false,
                    error: 'Users table not configured'
                });
            }

            // Check if user already exists
            console.log(`Checking if user exists with email: ${email}`);
            let existingUser = null;
            try {
                existingUser = await nocodbService.getUserByEmail(email);
                console.log('Existing user check result:', existingUser ? 'User exists' : 'User does not exist');
            } catch (error) {
                console.error('Error checking for existing user:', error.message);
                // Continue with creation if check fails - NocoDB will handle the unique constraint
            }

            if (existingUser) {
                console.log('Existing user found:', { id: existingUser.ID || existingUser.Id || existingUser.id, email: existingUser.Email || existingUser.email });
                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 exact column titles from NocoDB schema
            const userData = {
                Email: email,
                Name: name || '',
                Password: password,
                Phone: phone || '',
                Admin: isAdmin === true,
                'User Type': userType || 'user',
                ExpiresAt: expiresAt,
                ExpireDays: userType === 'temp' ? expireDays : null,
                'Last Login': null
            };

            const response = await nocodbService.create(
                nocodbService.tableIds.users,
                userData
            );

            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) {
            console.error('Error creating user:', error);

            // Check if it's a unique constraint violation (email already exists)
            if (error.response?.data?.code === '23505' ||
                error.response?.data?.message?.includes('already exists') ||
                error.message?.includes('already exists')) {
                return res.status(400).json({
                    success: false,
                    error: 'A user with this email address already exists'
                });
            }

            res.status(500).json({
                success: false,
                error: 'Failed to create user: ' + (error.message || 'Unknown error')
            });
        }
    }

    async delete(req, res) {
        try {
            const userId = req.params.id;

            if (!nocodbService.tableIds.users) {
                return res.status(500).json({
                    success: false,
                    error: 'Users table 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'
                });
            }

            await nocodbService.deleteUser(userId);

            res.json({
                success: true,
                message: 'User deleted successfully'
            });

        } catch (error) {
            console.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 (!nocodbService.tableIds.users) {
                return res.status(500).json({
                    success: false,
                    error: 'Users table not configured'
                });
            }

            // Get user data from database
            const user = await nocodbService.getById(
                nocodbService.tableIds.users,
                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) {
            console.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 (!nocodbService.tableIds.users) {
                return res.status(500).json({
                    success: false,
                    error: 'Users table not configured'
                });
            }

            // Get all users
            const response = await nocodbService.getAll(nocodbService.tableIds.users, {
                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');

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

                    console.log(`Sent broadcast email to: ${user.Email || user.email}`);
                } catch (emailError) {
                    console.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) {
            console.error('Error sending broadcast email:', error);
            res.status(500).json({
                success: false,
                error: 'Failed to send broadcast email'
            });
        }
    }
}

module.exports = new UsersController();