import { Response, NextFunction } from 'express';
import { adminService } from './admin.service';
import { AuthRequest } from '../../shared/middleware/auth';
import { ResponseFormatter } from '../../shared/utils/responseFormatter';

class AdminController {
  // ========== USERS ==========

  async findAllUsers(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const filters = {
        search: req.query.search as string | undefined,
        isActive: req.query.status === 'active' ? true : req.query.status === 'inactive' ? false : undefined,
        positionId: req.query.positionId as string | undefined,
        page: parseInt(req.query.page as string) || 1,
        pageSize: parseInt(req.query.pageSize as string) || 20,
      };
      const result = await adminService.findAllUsers(filters);
      res.json(ResponseFormatter.paginated(result.users, result.total, result.page, result.pageSize));
    } catch (error) {
      next(error);
    }
  }

  async findUserById(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const user = await adminService.findUserById(req.params.id);
      res.json(ResponseFormatter.success(user));
    } catch (error) {
      next(error);
    }
  }

  async createUser(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const userId = req.user!.id;
      const user = await adminService.createUser(
        {
          email: req.body.email,
          username: req.body.username,
          password: req.body.password,
          employeeId: req.body.employeeId,
          isActive: req.body.isActive ?? true,
        },
        userId
      );
      res.status(201).json(ResponseFormatter.success(user));
    } catch (error) {
      next(error);
    }
  }

  async updateUser(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const userId = req.user!.id;
      const user = await adminService.updateUser(
        req.params.id,
        {
          email: req.body.email,
          username: req.body.username,
          password: req.body.password,
          employeeId: req.body.employeeId,
          isActive: req.body.isActive,
        },
        userId
      );
      res.json(ResponseFormatter.success(user));
    } catch (error) {
      next(error);
    }
  }

  async toggleUserActive(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const userId = req.user!.id;
      const user = await adminService.toggleUserActive(req.params.id, userId);
      res.json(ResponseFormatter.success(user));
    } catch (error) {
      next(error);
    }
  }

  async deleteUser(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const userId = req.user!.id;
      await adminService.deleteUser(req.params.id, userId);
      res.json(ResponseFormatter.success(null, 'User deactivated successfully'));
    } catch (error) {
      next(error);
    }
  }

  // ========== AUDIT LOGS ==========

  async getAuditLogs(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const filters = {
        entityType: req.query.entityType as string | undefined,
        action: req.query.action as string | undefined,
        userId: req.query.userId as string | undefined,
        startDate: req.query.startDate as string | undefined,
        endDate: req.query.endDate as string | undefined,
        page: parseInt(req.query.page as string) || 1,
        pageSize: parseInt(req.query.pageSize as string) || 20,
      };
      const result = await adminService.getAuditLogs(filters);
      res.json(
        ResponseFormatter.paginated(result.logs, result.total, result.page, result.pageSize)
      );
    } catch (error) {
      next(error);
    }
  }

  // ========== STATS ==========

  async getStats(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const stats = await adminService.getStats();
      res.json(ResponseFormatter.success(stats));
    } catch (error) {
      next(error);
    }
  }

  // ========== POSITIONS (ROLES) ==========

  async getPositions(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const positions = await adminService.getPositions();
      res.json(ResponseFormatter.success(positions));
    } catch (error) {
      next(error);
    }
  }

  async createPosition(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const position = await adminService.createPosition({
        title: req.body.title,
        titleAr: req.body.titleAr,
        code: req.body.code,
        departmentId: req.body.departmentId,
        level: req.body.level,
        description: req.body.description,
        isActive: req.body.isActive,
      });
      res.status(201).json(ResponseFormatter.success(position));
    } catch (error) {
      next(error);
    }
  }

  async updatePosition(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const position = await adminService.updatePosition(req.params.id, {
        title: req.body.title,
        titleAr: req.body.titleAr,
        code: req.body.code,
        departmentId: req.body.departmentId,
        level: req.body.level,
        description: req.body.description,
        isActive: req.body.isActive,
      });
      res.json(ResponseFormatter.success(position));
    } catch (error) {
      next(error);
    }
  }

  async updatePositionPermissions(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const position = await adminService.updatePositionPermissions(
        req.params.id,
        req.body.permissions
      );
      res.json(ResponseFormatter.success(position));
    } catch (error) {
      next(error);
    }
  }

  // ========== PERMISSION GROUPS (Phase 3) ==========

  async getPermissionGroups(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const groups = await adminService.getPermissionGroups();
      res.json(ResponseFormatter.success(groups));
    } catch (error) {
      next(error);
    }
  }

  async createPermissionGroup(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const group = await adminService.createPermissionGroup(req.body);
      res.status(201).json(ResponseFormatter.success(group));
    } catch (error) {
      next(error);
    }
  }

  async updatePermissionGroup(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const group = await adminService.updatePermissionGroup(req.params.id, req.body);
      res.json(ResponseFormatter.success(group));
    } catch (error) {
      next(error);
    }
  }

  async updatePermissionGroupPermissions(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const group = await adminService.updatePermissionGroupPermissions(
        req.params.id,
        req.body.permissions
      );
      res.json(ResponseFormatter.success(group));
    } catch (error) {
      next(error);
    }
  }

  async getUserRoles(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const roles = await adminService.getUserRoles(req.params.userId);
      res.json(ResponseFormatter.success(roles));
    } catch (error) {
      next(error);
    }
  }

  async assignUserRole(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      const userRole = await adminService.assignUserRole(req.params.userId, req.body.roleId);
      res.status(201).json(ResponseFormatter.success(userRole));
    } catch (error) {
      next(error);
    }
  }

  async removeUserRole(req: AuthRequest, res: Response, next: NextFunction) {
    try {
      await adminService.removeUserRole(req.params.userId, req.params.roleId);
      res.json(ResponseFormatter.success({ success: true }));
    } catch (error) {
      next(error);
    }
  }
}

export const adminController = new AdminController();
