/**
 * Admin Impersonation Routes
 * Allows admins to login as users for support/debugging
 */

const express = require('express');
const { requireAdmin, authenticateToken } = require('../middleware/authMiddleware');
const impersonationService = require('../services/ImpersonationService');
const BreadcrumbService = require('../services/BreadcrumbService');

const router = express.Router();

/**
 * POST /api/admin/users/:userId/impersonate
 * Start impersonating a user
 */
router.post('/users/:userId/impersonate', requireAdmin, async (req, res) => {
  try {
    const { userId } = req.params;
    const adminUser = req.user;

    console.log(`[Impersonation] Admin ${adminUser.userId} starting impersonation of user ${userId}`);

    // Get database pool from app
    const { pool } = req.app.locals;
    if (!pool) {
      return res.status(500).json({
        success: false,
        error: 'Database connection not available'
      });
    }

    // Validate that user exists
    const [users] = await pool.execute(
      'SELECT id, email, first_name, last_name, role, status FROM users WHERE id = ? LIMIT 1',
      [userId]
    );

    if (!users || users.length === 0) {
      return res.status(404).json({
        success: false,
        error: 'User not found'
      });
    }

    const targetUser = users[0];

    // Prevent impersonating other admins
    if (targetUser.role === 'admin') {
      console.warn(`[Impersonation] Admin ${adminUser.userId} attempted to impersonate admin user ${userId}`);
      return res.status(403).json({
        success: false,
        error: 'Cannot impersonate another admin',
        message: 'For security reasons, you cannot impersonate other administrators'
      });
    }

    // Prevent impersonating banned/suspended users
    if (targetUser.status !== 'active') {
      return res.status(400).json({
        success: false,
        error: `User is ${targetUser.status}`,
        message: `Cannot impersonate a ${targetUser.status} user`
      });
    }

    // Start impersonation
    const impersonationResult = await impersonationService.startImpersonation(adminUser, targetUser);

    if (!impersonationResult.success) {
      return res.status(500).json({
        success: false,
        error: 'Failed to start impersonation',
        details: impersonationResult.error
      });
    }

    // Log the impersonation activity
    await impersonationService.logImpersonationActivity(
      pool,
      adminUser.userId,
      userId,
      'impersonation_started',
      {
        userEmail: targetUser.email,
        userName: `${targetUser.first_name} ${targetUser.last_name}`,
        ipAddress: req.ip,
        userAgent: req.headers['user-agent']
      }
    );

    console.log(`[Impersonation] ✅ Successfully started impersonation: admin ${adminUser.userId} → user ${userId}`);

    res.json({
      success: true,
      message: `Impersonation started for ${targetUser.first_name} ${targetUser.last_name}`,
      token: impersonationResult.token,
      impersonation: impersonationResult.impersonation
    });
  } catch (error) {
    console.error('[Impersonation] Error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to start impersonation',
      details: error.message
    });
  }
});

/**
 * POST /api/admin/impersonate/stop
 * Stop impersonating and return to admin account
 * Uses authenticateToken only (not requireAdmin) because the active token has the impersonated user's role
 */
router.post('/impersonate/stop', authenticateToken, async (req, res) => {
  try {
    // Check if user is impersonating
    if (!req.user.impersonating) {
      return res.status(400).json({
        success: false,
        error: 'Not currently impersonating',
        message: 'You are not currently impersonating a user'
      });
    }

    const adminId = req.user.impersonatorId;
    const targetUserId = req.user.userId;

    console.log(`[Impersonation] Stopping impersonation: admin ${adminId} → user ${targetUserId}`);

    // Get database pool
    const { pool } = req.app.locals;
    if (pool) {
      // Log the impersonation end
      await impersonationService.logImpersonationActivity(
        pool,
        adminId,
        targetUserId,
        'impersonation_ended',
        {
          duration: new Date() - new Date(req.user.startedAt),
          ipAddress: req.ip
        }
      );
    }

    // Generate new admin token
    const jwt = require('jsonwebtoken');
    const newToken = jwt.sign(
      {
        userId: adminId,
        role: 'admin'
      },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }
    );

    console.log(`[Impersonation] ✅ Successfully stopped impersonation`);

    res.json({
      success: true,
      message: 'Impersonation stopped. Returning to admin account.',
      token: newToken
    });
  } catch (error) {
    console.error('[Impersonation] Error stopping impersonation:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to stop impersonation',
      details: error.message
    });
  }
});

/**
 * GET /api/admin/impersonate/info
 * Get current impersonation status
 */
router.get('/impersonate/info', (req, res) => {
  // Check if we have a token
  const authHeader = req.headers['authorization'];
  if (!authHeader) {
    return res.status(401).json({
      success: false,
      error: 'No token provided'
    });
  }

  try {
    const token = authHeader.split(' ')[1];
    const jwt = require('jsonwebtoken');
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    if (!decoded.impersonating) {
      return res.json({
        success: true,
        impersonating: false,
        message: 'Not currently impersonating'
      });
    }

    return res.json({
      success: true,
      impersonating: true,
      targetUser: {
        id: decoded.userId,
        email: decoded.email,
        role: decoded.role
      },
      admin: {
        id: decoded.impersonatorId,
        email: decoded.impersonatorEmail
      },
      startedAt: decoded.startedAt
    });
  } catch (error) {
    res.status(401).json({
      success: false,
      error: 'Invalid token',
      impersonating: false
    });
  }
});

module.exports = router;
