using AutoMapper; using Azure; using Marco.Pms.CacheHelper; using Marco.Pms.Model.AppMenu; using Marco.Pms.Model.Dtos.AppMenu; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.AppMenu; using Marco.Pms.Services.Service; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using MongoDB.Driver; using Org.BouncyCastle.Asn1.Ocsp; using System.Linq; using System.Threading.Tasks; using static System.Collections.Specialized.BitVector32; namespace Marco.Pms.Services.Controllers { [Authorize] [ApiController] [Route("api/[controller]")] public class AppMenuController : ControllerBase { private readonly UserHelper _userHelper; private readonly EmployeeHelper _employeeHelper; private readonly RolesHelper _rolesHelper; private readonly SideBarMenu _sideBarMenuHelper; private readonly IMapper _mapper; private readonly ILoggingService _logger; private readonly PermissionServices _permissions; public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger, PermissionServices permissions) { _userHelper = userHelper; _employeeHelper = employeeHelper; _rolesHelper = rolesHelper; _sideBarMenuHelper = sideBarMenuHelper; _mapper = mapper; _logger = logger; _permissions = permissions; } [HttpPost("sidebar/menu-section")] public async Task CreateAppSideBarMenu([FromBody] MenuSectionDto MenuSecetion) { var user = await _userHelper.GetCurrentEmployeeAsync(); if (!(user.ApplicationUser?.IsRootUser ?? false)) { _logger.LogWarning("Access Denied while creating side menu"); return StatusCode(403, ApiResponse.ErrorResponse("access denied", "User haven't permission", 403)); } var sideMenuSection = _mapper.Map(MenuSecetion); try { sideMenuSection = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenuSection); } catch (Exception ex) { _logger.LogError(ex, "Error Occurred while creating Menu"); return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } if (sideMenuSection == null) { _logger.LogWarning("Error Occurred while creating Menu"); return BadRequest(ApiResponse.ErrorResponse("Invalid MenuSection", 400)); } _logger.LogInfo("Error Occurred while creating Menu"); return Ok(ApiResponse.SuccessResponse(sideMenuSection, "Sidebar menu created successfully.", 201)); } [HttpPut("sidebar/menu-section/{sectionId}")] public async Task UpdateMenuSection(Guid sectionId, [FromBody] MenuSection updatedSection) { if (sectionId == Guid.Empty || updatedSection == null) { _logger.LogWarning("Error Occurred while Updating Menu Item"); return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); } var UpdatedMenuSection = _mapper.Map(updatedSection); try { UpdatedMenuSection = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, UpdatedMenuSection); if (UpdatedMenuSection == null) return NotFound(ApiResponse.ErrorResponse("Menu section not found", 404)); return Ok(ApiResponse.SuccessResponse(UpdatedMenuSection, "Menu section updated successfully")); } catch (Exception ex) { _logger.LogError(ex, "Failed to update menu section"); return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); } } [HttpPost("sidebar/menus/{sectionId}/items")] public async Task AddMenuItem(Guid sectionId, [FromBody] MenuItemDto newItemDto) { if (sectionId == Guid.Empty || newItemDto == null) return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); try { var menuItem = _mapper.Map(newItemDto); var result = await _sideBarMenuHelper.AddMenuItemAsync(sectionId, menuItem); if (result == null) return NotFound(ApiResponse.ErrorResponse("Menu section not found", 404)); _logger.LogInfo("Added MenuItem in Section: {SectionId}"); return Ok(ApiResponse.SuccessResponse(result, "Menu item added successfully")); } catch (Exception ex) { _logger.LogError(ex, "Error occurred while adding MenuItem inside MenuSection: {SectionId}", sectionId); return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); } } [HttpPut("sidebar/{sectionId}/items/{itemId}")] public async Task UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] MenuItemDto updatedMenuItem) { if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null) { _logger.LogWarning("Error Occurred while Updating Menu Item"); return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); } var sideMenuItem = _mapper.Map(updatedMenuItem); try { sideMenuItem = await _sideBarMenuHelper.UpdateMenuItemAsync(sectionId, itemId, sideMenuItem); if (sideMenuItem == null) { _logger.LogWarning("Error Occurred while Updating SidBar Section:{SectionId} MenuItem:{itemId} "); return BadRequest(ApiResponse.ErrorResponse("Menu creation failed", 400)); } _logger.LogInfo("SidBar Section{SectionId} MenuItem {itemId} Updated "); return Ok(ApiResponse.SuccessResponse(sideMenuItem, "Sidebar MenuItem Updated successfully.", 201)); } catch (Exception ex) { _logger.LogError(ex, "Error Occurred while creating MenuItem"); return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } } [HttpPost("sidebar/menus/{sectionId}/items/{itemId}/subitems")] public async Task AddSubMenuItem(Guid sectionId, Guid itemId, [FromBody] SubMenuItemDto newSubItem) { if (sectionId == Guid.Empty || itemId == Guid.Empty || newSubItem == null) return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); try { var subMenuItem = _mapper.Map(newSubItem); var result = await _sideBarMenuHelper.AddSubMenuItemAsync(sectionId, itemId, subMenuItem); if (result == null) { return NotFound(ApiResponse.ErrorResponse("Menu item not found", 404)); } _logger.LogInfo("Added SubMenuItem in Section: {SectionId}, MenuItem: {ItemId}"); return Ok(ApiResponse.SuccessResponse(result, "Submenu item added successfully")); } catch (Exception ex) { _logger.LogError(ex, "Failed to add submenu item"); return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); } } [HttpPut("sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")] public async Task UpdateSubmenuItem(Guid sectionId, Guid itemId, Guid subItemId, [FromBody] SubMenuItemDto updatedSubMenuItem) { if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem == null) return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); try { var SubMenuItem = _mapper.Map(updatedSubMenuItem); SubMenuItem = await _sideBarMenuHelper.UpdateSubmenuItemAsync(sectionId, itemId, subItemId, SubMenuItem); if (SubMenuItem == null) return NotFound(ApiResponse.ErrorResponse("Submenu item not found", 404)); _logger.LogInfo("SidBar Section{SectionId} MenuItem {itemId} SubMenuItem {subItemId} Updated"); return Ok(ApiResponse.SuccessResponse(SubMenuItem, "Submenu item updated successfully")); } catch (Exception ex) { _logger.LogError(ex, "Error Occurred while Updating Sub-MenuItem"); return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } } [HttpGet("sidebar/menu-section")] public async Task GetAppSideBarMenu() { var loggedUser = await _userHelper.GetCurrentUserAsync(); var employeeId = Guid.Parse(loggedUser.Id); var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); foreach (var menu in menus) { var allowedItems = new List(); foreach (var item in menu.Items) { bool isAllowed = false; if (item.PermissionKeys == null || !item.PermissionKeys.Any()) { isAllowed = true; } else { foreach (var pk in item.PermissionKeys) { if (Guid.TryParse(pk, out var permissionId)) { if (await _permissions.HasPermission(employeeId, permissionId)) { isAllowed = true; break; } } } } if (isAllowed) { if (item.Submenu != null && item.Submenu.Any()) { var allowedSubmenus = new List(); foreach (var sm in item.Submenu) { bool smAllowed = false; if (sm.PermissionKeys == null || !sm.PermissionKeys.Any()) { smAllowed = true; } else { foreach (var pk in sm.PermissionKeys) { if (Guid.TryParse(pk, out var permissionId)) { if (await _permissions.HasPermission(employeeId, permissionId)) { smAllowed = true; break; } } } } if (smAllowed) allowedSubmenus.Add(sm); } item.Submenu = allowedSubmenus; } allowedItems.Add(item); } } menu.Items = allowedItems; } return Ok(menus); } } }