const UnitOfWork = require('../../database/UnitOfWork');
const AdminService = require('../../services/admin/AdminService');

class AdminUserController {
  static async getUserStats(req, res) {
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const stats = await AdminService.getUserStats(unitOfWork);
      await unitOfWork.commit();
      res.json({ success: true, stats });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async getUserList(req, res) {
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const users = await AdminService.getUserList(unitOfWork);
      await unitOfWork.commit();
      res.json({ success: true, users });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async getVerificationPendingUsers(req, res) {
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const users = await AdminService.getVerificationPendingUsers(unitOfWork);
      await unitOfWork.commit();
      res.json({ success: true, users });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async getUnverifiedUsers(req, res) {
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const users = await AdminService.getUnverifiedUsers(unitOfWork);
      await unitOfWork.commit();
      res.json({ success: true, users });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async verifyUser(req, res) {
    const userId = req.params.id;
    const { permissions = [] } = req.body;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const result = await AdminService.verifyUser(unitOfWork, userId, permissions);
      await unitOfWork.commit();
      res.json({ success: true, ...result });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async getFullUserAccountDetails(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden' });
    }
    const userId = req.params.id;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const details = await AdminService.getFullUserAccountDetails(unitOfWork, userId);
      await unitOfWork.commit();
      res.json({ success: true, ...details });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async getDetailedUserInfo(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden' });
    }
    const userId = req.params.id;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const details = await AdminService.getDetailedUserInfo(unitOfWork, userId);
      await unitOfWork.commit();
      res.json({ success: true, ...details });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async updateUserPermissions(req, res) {
    const userId = Number(req.params.id);
    const permissions = req.body.permissions;
    if (!Array.isArray(permissions) || permissions.some(p => typeof p !== 'string')) {
      return res.status(400).json({ success: false, message: 'Invalid permissions format.' });
    }
    if (!req.user || req.user.role !== 'admin') {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.updateUserPermissions(unitOfWork, userId, permissions);
      await unitOfWork.commit();
      return res.json({ success: true, message: 'Permissions updated.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      return res.status(500).json({ success: false, message: error.message });
    }
  }

  static async deleteUser(req, res) {
    if (!req.user || req.user.role !== 'admin') {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.deleteUser(unitOfWork, userId);
      await unitOfWork.commit();
      res.json({ success: true, message: 'User deleted.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async archiveUser(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.archiveUser(unitOfWork, userId);
      await unitOfWork.commit();
      res.json({ success: true, message: 'User archived successfully.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async unarchiveUser(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.unarchiveUser(unitOfWork, userId);
      await unitOfWork.commit();
      res.json({ success: true, message: 'User unarchived successfully.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async updateUserVerification(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const { is_admin_verified } = req.body;
    
    if (typeof is_admin_verified !== 'number' || (is_admin_verified !== 0 && is_admin_verified !== 1)) {
      return res.status(400).json({ success: false, message: 'Invalid is_admin_verified value. Must be 0 or 1.' });
    }
    
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.updateUserVerification(unitOfWork, userId, is_admin_verified);
      await unitOfWork.commit();
      res.json({ success: true, message: 'User verification status updated successfully.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async updateUserProfile(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const { profileData, userType } = req.body;
    
    if (!profileData || !userType) {
      return res.status(400).json({ success: false, message: 'Missing profileData or userType.' });
    }
    
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      await AdminService.updateUserProfile(unitOfWork, userId, profileData, userType);
      await unitOfWork.commit();
      res.json({ success: true, message: 'User profile updated successfully.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }

  static async updateUserStatus(req, res) {
    if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
      return res.status(403).json({ success: false, message: 'Forbidden: Admins only.' });
    }
    const userId = req.params.id;
    const { status } = req.body;
    
    if (!status) {
      return res.status(400).json({ success: false, message: 'Missing status.' });
    }
    
    const unitOfWork = new UnitOfWork();
    await unitOfWork.start();
    try {
      const result = await AdminService.updateUserStatus(unitOfWork, userId, status);
      await unitOfWork.commit();
      res.json({ success: true, message: result.message || 'User status updated successfully.' });
    } catch (error) {
      await unitOfWork.rollback(error);
      res.status(500).json({ success: false, message: error.message });
    }
  }
}

module.exports = AdminUserController;