/**
 * Admin User Management Routes
 * Complete user management endpoints
 */

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

const router = express.Router();

/**
 * GET /api/admin/users
 * List all users with filtering and pagination
 */
router.get('/users', requireAdmin, async (req, res) => {
  try {
    const { page = 1, limit = 20, search = '', status = '', role = '' } = req.query;
    const offset = (page - 1) * limit;

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

    // Build where clause
    let whereClause = 'WHERE 1=1';
    let params = [];

    if (search) {
      whereClause += ' AND (email LIKE ? OR first_name LIKE ? OR last_name LIKE ?)';
      const searchParam = `%${search}%`;
      params.push(searchParam, searchParam, searchParam);
    }

    if (status) {
      whereClause += ' AND status = ?';
      params.push(status);
    }

    if (role) {
      whereClause += ' AND role = ?';
      params.push(role);
    }

    // Get users
    const [users] = await pool.execute(
      `SELECT id, username, email, first_name, last_name, balance, role, status,
              email_verified, mobile_verified, created_at, last_login_at
       FROM users ${whereClause}
       ORDER BY created_at DESC
       LIMIT ? OFFSET ?`,
      [...params, parseInt(limit), offset]
    );

    // Get total count
    const [countResult] = await pool.execute(
      `SELECT COUNT(*) as total FROM users ${whereClause}`,
      params
    );

    const total = countResult[0].total;

    res.json({
      success: true,
      users,
      pagination: {
        page: parseInt(page),
        limit: parseInt(limit),
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error) {
    console.error('[Admin Users] Error listing users:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to list users',
      details: error.message
    });
  }
});

/**
 * GET /api/admin/users/:userId
 * Get detailed user information
 */
router.get('/users/:userId', requireAdmin, async (req, res) => {
  try {
    const { userId } = req.params;

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

    // Get user details
    const [users] = await pool.execute(
      'SELECT * FROM users WHERE id = ? LIMIT 1',
      [userId]
    );

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

    const user = users[0];

    // Get user statistics
    const [ordersResult] = await pool.execute(
      'SELECT COUNT(*) as count FROM orders WHERE user_id = ?',
      [userId]
    );

    const [depositsResult] = await pool.execute(
      'SELECT SUM(amount) as total FROM deposits WHERE user_id = ? AND status = ?',
      [userId, 'approved']
    );

    const [transactionsResult] = await pool.execute(
      'SELECT COUNT(*) as count FROM transactions WHERE user_id = ?',
      [userId]
    );

    const [loginActivitiesResult] = await pool.execute(
      'SELECT * FROM login_activities WHERE user_id = ? ORDER BY login_at DESC LIMIT 5',
      [userId]
    );

    res.json({
      success: true,
      user,
      stats: {
        totalOrders: ordersResult[0].count,
        totalDeposited: depositsResult[0].total || 0,
        totalTransactions: transactionsResult[0].count
      },
      recentLogins: loginActivitiesResult
    });
  } catch (error) {
    console.error('[Admin Users] Error getting user details:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to get user details',
      details: error.message
    });
  }
});

/**
 * PUT /api/admin/users/:userId/status
 * Update user status (active, banned, suspended)
 */
router.put('/users/:userId/status', requireAdmin, async (req, res) => {
  try {
    const { userId } = req.params;
    const { status, reason } = req.body;

    const validStatuses = ['active', 'banned', 'suspended'];
    if (!validStatuses.includes(status)) {
      return res.status(400).json({
        success: false,
        error: 'Invalid status',
        validStatuses
      });
    }

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

    // Get user first
    const [users] = await pool.execute(
      'SELECT * FROM users WHERE id = ? LIMIT 1',
      [userId]
    );

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

    const user = users[0];

    // Prevent changing admin status
    if (user.role === 'admin') {
      return res.status(403).json({
        success: false,
        error: 'Cannot change admin status',
        message: 'Administrator accounts cannot be modified this way'
      });
    }

    // Update user status
    await pool.execute(
      'UPDATE users SET status = ?, updated_at = NOW() WHERE id = ?',
      [status, userId]
    );

    // Log the action
    console.log(`[Admin Users] User ${userId} status changed to ${status} by admin ${req.user.userId}`);

    // Add notification if status changed
    if (user.status !== status) {
      const message = status === 'banned'
        ? 'Your account has been suspended by administration.'
        : `Your account status has been changed to ${status}.`;

      await pool.execute(
        `INSERT INTO notifications (user_id, sender_id, type, subject, message, sent_at)
         VALUES (?, ?, ?, ?, ?, NOW())`,
        [userId, req.user.userId, 'account_status', 'Account Status Changed', message]
      );
    }

    res.json({
      success: true,
      message: `User status updated to ${status}`,
      user: {
        id: userId,
        previousStatus: user.status,
        newStatus: status
      }
    });
  } catch (error) {
    console.error('[Admin Users] Error updating user status:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to update user status',
      details: error.message
    });
  }
});

/**
 * POST /api/admin/users/:userId/balance
 * Adjust user account balance (add or subtract)
 */
router.post('/users/:userId/balance', requireAdmin, async (req, res) => {
  try {
    const { userId } = req.params;
    const { amount, type, reason } = req.body; // type: 'add' or 'subtract'

    if (!amount || !type || !reason) {
      return res.status(400).json({
        success: false,
        error: 'Missing required fields',
        required: ['amount', 'type', 'reason']
      });
    }

    if (!['add', 'subtract'].includes(type)) {
      return res.status(400).json({
        success: false,
        error: 'Invalid type',
        validTypes: ['add', 'subtract']
      });
    }

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

    // Get current balance
    const [users] = await pool.execute(
      'SELECT balance FROM users WHERE id = ?',
      [userId]
    );

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

    const currentBalance = parseFloat(users[0].balance);
    const changeAmount = parseFloat(amount);
    const newBalance = type === 'add' ? currentBalance + changeAmount : currentBalance - changeAmount;

    if (newBalance < 0) {
      return res.status(400).json({
        success: false,
        error: 'Insufficient balance',
        message: `User does not have enough balance to subtract ${changeAmount}`,
        currentBalance
      });
    }

    // Update balance
    await pool.execute(
      'UPDATE users SET balance = ?, updated_at = NOW() WHERE id = ?',
      [newBalance, userId]
    );

    // Record transaction
    await pool.execute(
      `INSERT INTO transactions (user_id, type, amount, post_balance, description, created_at)
       VALUES (?, ?, ?, ?, ?, NOW())`,
      [
        userId,
        type === 'add' ? 'bonus' : 'admin_withdrawal',
        type === 'add' ? changeAmount : -changeAmount,
        newBalance,
        `Admin ${type === 'add' ? 'added' : 'subtracted'} ₦${changeAmount.toFixed(2)}: ${reason}`
      ]
    );

    console.log(`[Admin Users] Balance adjustment for user ${userId}: ${type} ${changeAmount}`);

    res.json({
      success: true,
      message: `Balance ${type === 'add' ? 'added' : 'subtracted'}`,
      adjustment: {
        userId,
        previousBalance: currentBalance,
        newBalance,
        amount: changeAmount,
        type,
        reason
      }
    });
  } catch (error) {
    console.error('[Admin Users] Error adjusting balance:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to adjust balance',
      details: error.message
    });
  }
});

/**
 * DELETE /api/admin/users/:userId
 * Soft delete a user (mark as deleted but keep data)
 */
router.delete('/users/:userId', requireAdmin, async (req, res) => {
  try {
    const { userId } = req.params;
    const adminId = req.user.userId;

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

    // Get user
    const [users] = await pool.execute(
      'SELECT * FROM users WHERE id = ?',
      [userId]
    );

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

    const user = users[0];

    // Prevent deleting admins
    if (user.role === 'admin') {
      return res.status(403).json({
        success: false,
        error: 'Cannot delete admin users',
        message: 'Administrator accounts cannot be deleted'
      });
    }

    // Soft delete user
    await pool.execute(
      'UPDATE users SET status = ?, updated_at = NOW() WHERE id = ?',
      ['deleted', userId]
    );

    console.log(`[Admin Users] User ${userId} deleted by admin ${adminId}`);

    res.json({
      success: true,
      message: 'User deleted successfully',
      user: {
        id: userId,
        email: user.email,
        deletedAt: new Date()
      }
    });
  } catch (error) {
    console.error('[Admin Users] Error deleting user:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to delete user',
      details: error.message
    });
  }
});

module.exports = router;
