// Account management routes for registered users
const express = require('express')
const router = express.Router()
const { requireAuth } = require('../middleware/auth')
const { body, validationResult } = require('express-validator')
const templateContext = require('../template-context')

// GET /account - Account dashboard
router.get('/account', requireAuth, async(req, res) => {
    try {
        const config = req.app.get('config')
        const userRepository = req.app.get('userRepository')
        const inboxLock = req.app.get('inboxLock')
        const mailProcessingService = req.app.get('mailProcessingService')
        const Helper = require('../../../application/helper-service')
        const helper = new Helper()

        // In UX debug mode, reset mock data to initial state only on fresh page load
        // (not on redirects after form submissions)
        if (config.uxDebugMode && userRepository && userRepository.reset) {
            // Check if this is a redirect from a form submission
            const isRedirect = req.session.accountSuccess || req.session.accountError

            if (!isRedirect) {
                // This is a fresh page load, reset to initial state
                userRepository.reset()
                if (inboxLock && inboxLock.reset) {
                    inboxLock.reset()
                }
            }
        }

        // Get user's verified forwarding emails
        const forwardEmails = userRepository.getForwardEmails(req.session.userId)

        // Get user's locked inboxes (if locking is available)
        let lockedInboxes = []
        if (inboxLock) {
            lockedInboxes = inboxLock.getUserLockedInboxes(req.session.userId)
        }

        // Get user stats
        const stats = userRepository.getUserStats(req.session.userId, config.user)

        const successMessage = req.session.accountSuccess
        const errorMessage = req.session.accountError
        delete req.session.accountSuccess
        delete req.session.accountError

        res.render('account', templateContext.build(req, {
            title: 'Account Dashboard',
            username: req.session.username,
            forwardEmails,
            lockedInboxes,
            stats,
            successMessage,
            errorMessage
        }))
    } catch (error) {
        console.error('Account page error:', error)
        res.status(500).render('error', {
            message: 'Failed to load account page',
            error: error
        })
    }
})

// POST /account/forward-email/add - Add forwarding email (triggers verification)
router.post('/account/forward-email/add',
    requireAuth, [
        body('email').isEmail().normalizeEmail().withMessage('Invalid email address')
    ],
    async(req, res) => {
        const errors = validationResult(req)
        if (!errors.isEmpty()) {
            req.session.accountError = errors.array()[0].msg
            return res.redirect('/account')
        }

        try {
            const userRepository = req.app.get('userRepository')
            const smtpService = req.app.get('smtpService')
            const verificationStore = req.app.get('verificationStore')
            const config = req.app.get('config')
            const crypto = require('crypto')
            const { email } = req.body

            // Check if already verified
            if (userRepository.hasForwardEmail(req.session.userId, email)) {
                req.session.accountError = 'This email is already verified on your account'
                return res.redirect('/account')
            }

            // Check limit
            const emailCount = userRepository.getForwardEmailCount(req.session.userId)
            if (emailCount >= config.user.maxForwardEmails) {
                req.session.accountError = `Maximum ${config.user.maxForwardEmails} forwarding emails allowed`
                return res.redirect('/account')
            }

            // Generate verification token
            const token = crypto.randomBytes(32).toString('hex')
            verificationStore.createVerification(token, email, {
                userId: req.session.userId
            })

            // Send verification email
            const baseUrl = config.http.baseUrl
            const branding = (config.http.features.branding || ['48hr.email'])[0]

            await smtpService.sendVerificationEmail(
                email,
                token,
                baseUrl,
                branding,
                '/account/verify'
            )

            req.session.accountSuccess = `Verification email sent to ${email}. Check your inbox!`
            res.redirect('/account')
        } catch (error) {
            console.error('Add forward email error:', error)
            req.session.accountError = 'Failed to send verification email. Please try again.'
            res.redirect('/account')
        }
    }
)

// GET /account/verify - Verify forwarding email
router.get('/account/verify', requireAuth, async(req, res) => {
    const { token } = req.query

    if (!token) {
        req.session.accountError = 'Invalid verification link'
        return res.redirect('/account')
    }

    try {
        const verificationStore = req.app.get('verificationStore')
        const userRepository = req.app.get('userRepository')

        const verification = verificationStore.verifyToken(token)

        if (!verification) {
            req.session.accountError = 'Verification link expired or invalid'
            return res.redirect('/account')
        }

        // Check if token belongs to this user
        if (verification.metadata.userId !== req.session.userId) {
            req.session.accountError = 'This verification link belongs to another account'
            return res.redirect('/account')
        }

        // Add email to user's verified emails
        userRepository.addForwardEmail(req.session.userId, verification.destinationEmail)

        req.session.accountSuccess = `Successfully verified ${verification.destinationEmail}!`
        res.redirect('/account')
    } catch (error) {
        console.error('Email verification error:', error)
        req.session.accountError = 'Failed to verify email. Please try again.'
        res.redirect('/account')
    }
})

// POST /account/forward-email/remove - Remove forwarding email
router.post('/account/forward-email/remove',
    requireAuth, [
        body('email').isEmail().normalizeEmail().withMessage('Invalid email address')
    ],
    async(req, res) => {
        const errors = validationResult(req)
        if (!errors.isEmpty()) {
            req.session.accountError = errors.array()[0].msg
            return res.redirect('/account')
        }

        try {
            const userRepository = req.app.get('userRepository')
            const { email } = req.body

            userRepository.removeForwardEmail(req.session.userId, email)

            req.session.accountSuccess = `Removed ${email} from your account`
            res.redirect('/account')
        } catch (error) {
            console.error('Remove forward email error:', error)
            req.session.accountError = 'Failed to remove email. Please try again.'
            res.redirect('/account')
        }
    }
)

// POST /account/locked-inbox/release - Release a locked inbox
router.post('/account/locked-inbox/release',
    requireAuth, [
        body('address').notEmpty().withMessage('Inbox address is required')
    ],
    async(req, res) => {
        const errors = validationResult(req)
        if (!errors.isEmpty()) {
            req.session.accountError = errors.array()[0].msg
            return res.redirect('/account')
        }

        try {
            const inboxLock = req.app.get('inboxLock')
            const { address } = req.body

            if (!inboxLock) {
                req.session.accountError = 'Inbox locking is not available'
                return res.redirect('/account')
            }

            // Check if user owns this locked inbox
            if (!inboxLock.isLockedByUser(address, req.session.userId)) {
                req.session.accountError = 'You do not own this locked inbox'
                return res.redirect('/account')
            }

            // Release the lock
            inboxLock.release(req.session.userId, address)

            req.session.accountSuccess = `Released lock on ${address}`
            res.redirect('/account')
        } catch (error) {
            console.error('Release inbox error:', error)
            req.session.accountError = 'Failed to release inbox. Please try again.'
            res.redirect('/account')
        }
    }
)

// POST /account/change-password - Change user password
router.post('/account/change-password',
    requireAuth,
    body('currentPassword').notEmpty().withMessage('Current password is required'),
    body('newPassword').isLength({ min: 8 }).withMessage('New password must be at least 8 characters'),
    body('confirmNewPassword').notEmpty().withMessage('Password confirmation is required'),
    async(req, res) => {
        try {
            const config = req.app.get('config')
                // Block password change in UX debug mode
            if (config.uxDebugMode) {
                req.session.accountError = 'Password changes are disabled in UX debug mode'
                return res.redirect('/account')
            }

            const errors = validationResult(req)
            if (!errors.isEmpty()) {
                req.session.accountError = errors.array()[0].msg
                return res.redirect('/account')
            }

            const { currentPassword, newPassword, confirmNewPassword } = req.body

            // Check if new passwords match
            if (newPassword !== confirmNewPassword) {
                req.session.accountError = 'New passwords do not match'
                return res.redirect('/account')
            }

            // Validate new password strength
            const hasUpperCase = /[A-Z]/.test(newPassword)
            const hasLowerCase = /[a-z]/.test(newPassword)
            const hasNumber = /[0-9]/.test(newPassword)

            if (!hasUpperCase || !hasLowerCase || !hasNumber) {
                req.session.accountError = 'Password must include uppercase, lowercase, and number'
                return res.redirect('/account')
            }

            const userRepository = req.app.get('userRepository')

            // Verify current password
            const isValidPassword = await userRepository.verifyPassword(req.session.userId, currentPassword)
            if (!isValidPassword) {
                req.session.accountError = 'Current password is incorrect'
                return res.redirect('/account')
            }

            // Update password
            await userRepository.updatePassword(req.session.userId, newPassword)

            req.session.accountSuccess = 'Password updated successfully'
            res.redirect('/account')
        } catch (error) {
            console.error('Change password error:', error)
            req.session.accountError = 'Failed to change password. Please try again.'
            res.redirect('/account')
        }
    }
)

// POST /account/delete - Permanently delete user account
router.post('/account/delete',
    requireAuth,
    body('password').notEmpty().withMessage('Password is required'),
    body('confirmText').equals('DELETE').withMessage('You must type DELETE to confirm'),
    async(req, res) => {
        try {
            const config = req.app.get('config')
                // Block account deletion in UX debug mode
            if (config.uxDebugMode) {
                req.session.accountError = 'Account deletion is disabled in UX debug mode'
                return res.redirect('/account')
            }

            const errors = validationResult(req)
            if (!errors.isEmpty()) {
                req.session.accountError = errors.array()[0].msg
                return res.redirect('/account')
            }

            const { password } = req.body
            const userRepository = req.app.get('userRepository')

            // Verify password
            const isValidPassword = await userRepository.verifyPassword(req.session.userId, password)
            if (!isValidPassword) {
                req.session.accountError = 'Incorrect password'
                return res.redirect('/account')
            }

            // Get user's locked inboxes to release them
            const inboxLock = req.app.get('inboxLock')
            if (inboxLock) {
                const lockedInboxes = inboxLock.getUserLockedInboxes(req.session.userId)
                for (const inbox of lockedInboxes) {
                    inboxLock.release(req.session.userId, inbox.address)
                }
            }

            // Delete user account
            await userRepository.deleteUser(req.session.userId)

            // Destroy session
            req.session.destroy((err) => {
                if (err) {
                    console.error('Session destroy error:', err)
                }
                res.redirect('/?deleted=true')
            })
        } catch (error) {
            console.error('Delete account error:', error)
            req.session.accountError = 'Failed to delete account. Please try again.'
            res.redirect('/account')
        }
    }
)

module.exports = router
