using LSFE.Domain.Contracts; using LSFE.Infrastructure.Database; using LSFE.Infrastructure.Dto.Account; using LSFE.Infrastructure.Entities; using Microsoft.AspNetCore.Identity; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using System.Data; namespace LSFE.Domain.Services.Account { public class NavigationService : INavigationService { private readonly LSFEDbContext _context; private readonly UserManager _userManager; public NavigationService(LSFEDbContext context, UserManager userManager) { _context = context; _userManager = userManager; } public async Task GetUserNavigationAsync(string userId) { try { var user = await _userManager.FindByIdAsync(userId); if (user == null) { return new NavigationResponseDto { Success = false, Message = "User not found or inactive", Data = new List() }; } // Get user roles using UserManager var roles = await _userManager.GetRolesAsync(user); if (!roles.Any()) { return new NavigationResponseDto { Success = false, Message = "User has no assigned roles", Data = new List() }; } // Get role IDs from role names var roleIds = await _context.Roles .Where(r => roles.Contains(r.Name)) .Select(r => r.Id) .ToListAsync(); // Get navigation for all user roles var navigationItems = await GetNavigationByRoleIdsAsync(roleIds); return new NavigationResponseDto { Success = true, Data = navigationItems, Message = "Navigation retrieved successfully" }; } catch (Exception ex) { return new NavigationResponseDto { Success = false, Message = $"Error retrieving navigation: {ex.Message}", Data = new List() }; } } public async Task> GetNavigationByRoleIdsAsync(List roleIds) { try { var roleIdsParam = string.Join(",", roleIds); using (var command = _context.Database.GetDbConnection().CreateCommand()) { command.CommandText = "GetUserNavigation"; command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@RoleIds", roleIdsParam)); await _context.Database.OpenConnectionAsync(); using (var result = await command.ExecuteReaderAsync()) { var rootModules = new List(); var childModules = new List(); // Read root modules while (await result.ReadAsync()) { rootModules.Add(new NavigationItemDto { Id = result["Id"].ToString(), Label = result["Label"].ToString(), Icon = result["Icon"].ToString(), Route = result["Route"].ToString(), Badge = result["Badge"]?.ToString(), Permissions = new PermissionsDto { CanView = Convert.ToBoolean(result["CanView"]), CanCreate = Convert.ToBoolean(result["CanCreate"]), CanEdit = Convert.ToBoolean(result["CanEdit"]), CanDelete = Convert.ToBoolean(result["CanDelete"]) }, Children = new List() }); } // Read child modules if (await result.NextResultAsync()) { while (await result.ReadAsync()) { childModules.Add(new NavigationItemDto { Id = result["Id"].ToString(), Label = result["Label"].ToString(), Icon = result["Icon"].ToString(), Route = result["Route"].ToString(), ParentModuleId = result["ParentModuleId"] != DBNull.Value ? Convert.ToInt32(result["ParentModuleId"]) : (int?)null, Permissions = new PermissionsDto { CanView = Convert.ToBoolean(result["CanView"]), CanCreate = Convert.ToBoolean(result["CanCreate"]), CanEdit = Convert.ToBoolean(result["CanEdit"]), CanDelete = Convert.ToBoolean(result["CanDelete"]) } }); } } // Attach children to parents foreach (var parent in rootModules) { var children = childModules .Where(c => c.ParentModuleId.ToString() == parent.Id) .ToList(); parent.Children = children.Any() ? children : null; } return rootModules; } } } catch (Exception ex) { Console.WriteLine($"Error in GetNavigationByRoleIdsAsync: {ex.Message}"); throw; } } // Optional: Add method to get single role navigation (for backwards compatibility) public async Task> GetNavigationByRoleAsync(string roleId) { return await GetNavigationByRoleIdsAsync(new List { roleId }); } } }