const express = require('express');
const router = express.Router();
const { executeQuery } = require('../config/database');
const { authenticateToken, requireMainAdmin, requireCompanyAdmin, requireManager } = require('../middleware/auth');
const {
  validateUserRegistration,
  validateId,
  validatePagination,
  handleValidationErrors
} = require('../middleware/validation');

// Get all users (Managers and above)
router.get('/', authenticateToken, requireManager, validatePagination(), handleValidationErrors, async (req, res) => {

  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const offset = (page - 1) * limit;
    const search = req.query.search || '';
    const role = req.query.role || '';
    const status = req.query.status || '';

    let whereClause = 'WHERE 1=1';
    let queryParams = [];

    if (search) {
      whereClause += ' AND (u.first_name LIKE ? OR u.last_name LIKE ? OR u.phone_number LIKE ?)';
      const searchPattern = `%${search}%`;
      queryParams.push(searchPattern, searchPattern, searchPattern);
    }

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

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

    // Get total count
    const countQuery = `
      SELECT COUNT(*) as total
      FROM users u
      ${whereClause}
    `;
    const countResult = await executeQuery(countQuery, queryParams);
    const total = countResult[0].total;

    // Get users with pagination
    const usersQuery = `
      SELECT 
        u.id, u.username, u.phone_number, u.first_name, u.last_name, 
        u.role, u.permission_level, u.company_id, u.status, u.profile_image, 
        u.created_at, u.updated_at,
        c.name as company_name,
        creator.first_name as creator_first_name, creator.last_name as creator_last_name
      FROM users u
      LEFT JOIN users creator ON u.created_by = creator.id
      LEFT JOIN companies c ON u.company_id = c.id
      ${whereClause}
      ORDER BY u.created_at DESC
      LIMIT ${limit} OFFSET ${offset}
    `;
    
    const users = await executeQuery(usersQuery, queryParams);

    res.status(200).json({
      success: true,
      message: 'Users retrieved successfully',
      data: {
        users,
        pagination: {
          current_page: page,
          per_page: limit,
          total,
          total_pages: Math.ceil(total / limit)
        }
      }
    });
  } catch (error) {
    console.error('Get users error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to retrieve users'
    });
  }
});

// Get user by ID (Managers and above)
router.get('/:id', authenticateToken, requireManager, validateId(), handleValidationErrors, async (req, res) => {
  const userId = req.params.id;

  try {
    let whereClause = 'WHERE u.id = ?';
    let queryParams = [userId];

    const users = await executeQuery(`
      SELECT 
        u.id, u.username, u.phone_number, u.first_name, u.last_name, 
        u.role, u.permission_level, u.company_id, u.status, u.profile_image, 
        u.created_at, u.updated_at,
        c.name as company_name,
        creator.first_name as creator_first_name, creator.last_name as creator_last_name
      FROM users u
      LEFT JOIN users creator ON u.created_by = creator.id
      LEFT JOIN companies c ON u.company_id = c.id
      ${whereClause}
    `, queryParams);

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

    res.status(200).json({
      success: true,
      message: 'User retrieved successfully',
      data: {
        user: users[0]
      }
    });
  } catch (error) {
    console.error('Get user error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to retrieve user'
    });
  }
});

// Create user
router.post('/', authenticateToken, requireCompanyAdmin, validateUserRegistration(), handleValidationErrors, async (req, res) => {
  try {
    const { phone_number, first_name, last_name, role = 'user', permission_level } = req.body;
    const createdBy = req.user.id;
    const companyId = req.user.company_id;

    // Check if user with phone number already exists
    const existingUsers = await executeQuery(
      'SELECT id FROM users WHERE phone_number = ?',
      [phone_number]
    );

    if (existingUsers.length > 0) {
      return res.status(400).json({
        success: false,
        message: 'User with this phone number already exists'
      });
    }

    // Role validation based on user's permission level
    const roleHierarchy = {
      user: 1,
      admin: 2,
      main_admin: 3
    };

    if (!roleHierarchy[role]) {
      return res.status(400).json({
        success: false,
        message: 'Invalid role specified'
      });
    }

    if (roleHierarchy[role] >= roleHierarchy[req.user.role]) {
      return res.status(403).json({
        success: false,
        message: 'You cannot create users with equal or higher privileges'
      });
    }

    const permissionLevelMap = {
      user: 1,
      admin: 2,
      main_admin: 3
    };
    const normalizedPermissionLevel = permission_level ?? permissionLevelMap[role];

    if (normalizedPermissionLevel < 1 || normalizedPermissionLevel > 3) {
      return res.status(400).json({
        success: false,
        message: 'Permission level must be between 1 and 3'
      });
    }

    if (normalizedPermissionLevel >= roleHierarchy[req.user.role]) {
      return res.status(403).json({
        success: false,
        message: 'You cannot create users with equal or higher privileges'
      });
    }

    // Generate username from phone number if not provided
    const username = `user_${phone_number}`;

    // Create user
    const result = await executeQuery(
      `INSERT INTO users (username, phone_number, first_name, last_name, role, permission_level, company_id, created_by, status) 
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'active')`,
      [username, phone_number, first_name, last_name, role, normalizedPermissionLevel, companyId, createdBy]
    );

    const newUserId = result.insertId;

    // Get created user details
    const newUser = await executeQuery(
      `SELECT 
        u.id, u.username, u.phone_number, u.first_name, u.last_name, 
        u.role, u.permission_level, u.company_id, u.status, u.created_at,
        c.name as company_name
       FROM users u
       LEFT JOIN companies c ON u.company_id = c.id
       WHERE u.id = ?`,
      [newUserId]
    );

    res.status(201).json({
      success: true,
      message: 'User created successfully',
      data: {
        user: newUser[0]
      }
    });
  } catch (error) {
    console.error('Create user error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to create user'
    });
  }
});

// Update user
router.put('/:id', authenticateToken, requireCompanyAdmin, validateId(), handleValidationErrors, async (req, res) => {
  try {
    const userId = req.params.id;
    const { first_name, last_name, role, status, permission_level } = req.body;

    // Check if user exists and belongs to the same company (for company admins)
    let whereClause = 'WHERE id = ?';
    let queryParams = [userId];

    const existingUsers = await executeQuery(
      `SELECT * FROM users ${whereClause}`,
      queryParams
    );

    if (existingUsers.length === 0) {
      return res.status(404).json({
        success: false,
        message: 'User not found or access denied'
      });
    }

    const existingUser = existingUsers[0];
    const targetIsAdminLevel = existingUser.role === 'admin' || existingUser.role === 'main_admin';
    if (targetIsAdminLevel && req.user.role !== 'main_admin') {
      return res.status(403).json({
        success: false,
        message: 'Only main admins can modify admin accounts'
      });
    }

    // Role validation based on user's permission level
    const roleHierarchy = {
      user: 1,
      admin: 2,
      main_admin: 3
    };

    if (role && !roleHierarchy[role]) {
      return res.status(400).json({
        success: false,
        message: 'Invalid role specified'
      });
    }

    if (role && roleHierarchy[role] >= roleHierarchy[req.user.role]) {
      return res.status(403).json({
        success: false,
        message: 'You cannot assign equal or higher privileges'
      });
    }

    const permissionLevelMap = {
      user: 1,
      admin: 2,
      main_admin: 3
    };

    let normalizedPermissionLevel;
    if (permission_level !== undefined) {
      normalizedPermissionLevel = permission_level;
    } else if (role) {
      normalizedPermissionLevel = permissionLevelMap[role];
    }

    if (normalizedPermissionLevel !== undefined && (normalizedPermissionLevel < 1 || normalizedPermissionLevel > 3)) {
      return res.status(400).json({
        success: false,
        message: 'Permission level must be between 1 and 3'
      });
    }

    if (
      normalizedPermissionLevel !== undefined &&
      normalizedPermissionLevel >= roleHierarchy[req.user.role]
    ) {
      return res.status(403).json({
        success: false,
        message: 'You cannot assign equal or higher privileges'
      });
    }

    // Build update query
    let updateFields = [];
    let updateValues = [];

    if (first_name !== undefined) {
      updateFields.push('first_name = ?');
      updateValues.push(first_name);
    }
    if (last_name !== undefined) {
      updateFields.push('last_name = ?');
      updateValues.push(last_name);
    }
    if (role !== undefined) {
      updateFields.push('role = ?');
      updateValues.push(role);
    }
    if (status !== undefined) {
      updateFields.push('status = ?');
      updateValues.push(status);
    }
    if (normalizedPermissionLevel !== undefined) {
      updateFields.push('permission_level = ?');
      updateValues.push(normalizedPermissionLevel);
    }

    if (updateFields.length === 0) {
      return res.status(400).json({
        success: false,
        message: 'No fields to update'
      });
    }

    updateFields.push('updated_at = NOW()');
    updateValues.push(userId);

    // Update user
    await executeQuery(
      `UPDATE users SET ${updateFields.join(', ')} WHERE id = ?`,
      updateValues
    );

    // Get updated user details
    const updatedUser = await executeQuery(
      `SELECT 
        u.id, u.username, u.phone_number, u.first_name, u.last_name, 
        u.role, u.permission_level, u.company_id, u.status, u.updated_at,
        c.name as company_name
       FROM users u
       LEFT JOIN companies c ON u.company_id = c.id
       WHERE u.id = ?`,
      [userId]
    );

    res.status(200).json({
      success: true,
      message: 'User updated successfully',
      data: {
        user: updatedUser[0]
      }
    });
  } catch (error) {
    console.error('Update user error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to update user'
    });
  }
});

// Delete user (Main Admin only)
router.delete('/:id', authenticateToken, requireMainAdmin, validateId(), handleValidationErrors, async (req, res) => {
  try {
    const userId = req.params.id;

    // Check if user exists
    const existingUsers = await executeQuery(
      'SELECT * FROM users WHERE id = ?',
      [userId]
    );

    if (existingUsers.length === 0) {
      return res.status(404).json({
        success: false,
        message: 'User not found'
      });
    }

    // Cannot delete self
    if (userId == req.user.id) {
      return res.status(400).json({
        success: false,
        message: 'Cannot delete your own account'
      });
    }

    // Cannot delete other main admins
    if (existingUsers[0].role === 'main_admin') {
      return res.status(403).json({
        success: false,
        message: 'Cannot delete other main admin accounts'
      });
    }

    // Soft delete user (set status to inactive)
    await executeQuery(
      'UPDATE users SET status = "inactive", updated_at = NOW() WHERE id = ?',
      [userId]
    );

    res.status(200).json({
      success: true,
      message: 'User deleted successfully'
    });
  } catch (error) {
    console.error('Delete user error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to delete user'
    });
  }
});

// Get user statistics (Company Admin and above)
router.get('/stats/overview', authenticateToken, requireCompanyAdmin, async (req, res) => {
  try {
    const stats = await executeQuery(`
      SELECT 
        COUNT(*) as total_users,
        SUM(CASE WHEN role = 'main_admin' THEN 1 ELSE 0 END) as main_admin_count,
        SUM(CASE WHEN role = 'admin' THEN 1 ELSE 0 END) as admin_count,
        SUM(CASE WHEN role = 'user' THEN 1 ELSE 0 END) as user_count,
        SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_users,
        SUM(CASE WHEN status = 'inactive' THEN 1 ELSE 0 END) as inactive_users,
        SUM(CASE WHEN created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN 1 ELSE 0 END) as new_users_last_30_days
      FROM users
    `);

    res.status(200).json({
      success: true,
      message: 'User statistics retrieved successfully',
      data: {
        stats: stats[0]
      }
    });
  } catch (error) {
    console.error('Get user stats error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to retrieve user statistics'
    });
  }
});

module.exports = router;
