using AutoMapper; using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Master; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Services.Helpers; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace MarcoBMS.Services.Controllers { [Route("api/[controller]")] [ApiController] // [Authorize] public class FeatureController : ControllerBase { private readonly ApplicationDbContext _context; private readonly GeneralHelper _generalHelper; //private readonly UserHelper _userHelper; private readonly IMapper _mapper; private readonly ILoggingService _logger; private readonly Guid tenantId; public FeatureController(ApplicationDbContext context, GeneralHelper generalHelper, UserHelper userHelper, IMapper mapper, ILoggingService logger) { _context = context; _generalHelper = generalHelper; //_userHelper = userHelper; _mapper = mapper; _logger = logger; tenantId = userHelper.GetTenantId(); } /// /// Converts FeaturePermissions from Feature entity into FeaturePermissionVM collection. /// /// Feature entity from DB /// Collection of FeaturePermissionVM, ordered by Name private ICollection GetFeaturePermissionVMs(Feature model) { if (model.FeaturePermissions == null || !model.FeaturePermissions.Any()) { _logger.LogInfo("No feature permissions found for Feature: {FeatureId}", model.Id); return new List(); } // Project and order feature permissions var features = model.FeaturePermissions .Select(p => _mapper.Map(p)) .OrderBy(f => f.Name) .ToList(); _logger.LogDebug("Mapped {Count} feature permissions for Feature: {FeatureId}", features.Count, model.Id); return features; } /// /// API endpoint to fetch all features and their permissions for the given tenant. /// [HttpGet] public async Task GetAllFeaturesAsync() { try { _logger.LogInfo("Fetching all features for tenant: {TenantId}", tenantId); var featureQuery = _context.Features .AsNoTracking(); // Optimization: Read-only query if (tenantId != Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26")) { // Step 1: Get tenant-specific FeatureIds List featureIds = await _generalHelper.GetFeatureIdsByTenentIdAsync(tenantId); if (featureIds == null || !featureIds.Any()) { _logger.LogWarning("No features found for tenant: {TenantId}", tenantId); return Ok(ApiResponse.SuccessResponse(new List(), "No features found.", 200)); } _logger.LogDebug("Retrieved {Count} feature IDs for tenant: {TenantId}", featureIds.Count, tenantId); // Step 2: Query Features with related FeaturePermissions & Module featureQuery = featureQuery.Where(f => featureIds.Contains(f.Id)); } var features = await featureQuery .Include(f => f.FeaturePermissions) .Include(f => f.Module).ToListAsync(); _logger.LogDebug("Fetched {Count} features from DB for tenant: {TenantId}", features.Count, tenantId); // Step 3: Map features to ViewModels var featureVMs = features .Select(c => new FeatureVM { Id = c.Id, Name = c.Name, Description = c.Description, FeaturePermissions = GetFeaturePermissionVMs(c), ModuleId = c.ModuleId, ModuleName = c.Module?.Name ?? string.Empty, IsActive = c.IsActive }) .OrderBy(f => f.Name) .ToList(); _logger.LogInfo("Returning {Count} features for tenant: {TenantId}", featureVMs.Count, tenantId); return Ok(ApiResponse.SuccessResponse(featureVMs, "Success.", 200)); } catch (Exception ex) { _logger.LogError(ex, "Error while fetching features for tenant: {TenantId}", tenantId); return StatusCode(500, ApiResponse.ErrorResponse("An unexpected error occurred.", 500)); } } } }