using AutoMapper;
using Marco.Pms.CacheHelper;
using Marco.Pms.Model.AppMenu;
using Marco.Pms.Model.Dtos.AppMenu;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.AppMenu;
using Marco.Pms.Model.ViewModels.DocumentManager;
using Marco.Pms.Services.Helpers;
using Marco.Pms.Services.Service;
using MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Marco.Pms.Services.Controllers
{
    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class AppMenuController : ControllerBase
    {

        private readonly UserHelper _userHelper;
        private readonly SidebarMenuHelper _sideBarMenuHelper;
        private readonly IMapper _mapper;
        private readonly ILoggingService _logger;
        private readonly IServiceScopeFactory _serviceScopeFactory;

        private readonly Guid tenantId;
        private static readonly Guid superTenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26");
        private static readonly Guid ProjectManagement = Guid.Parse("53176ebf-c75d-42e5-839f-4508ffac3def");
        private static readonly Guid ExpenseManagement = Guid.Parse("a4e25142-449b-4334-a6e5-22f70e4732d7");
        private static readonly Guid TaskManagement = Guid.Parse("9d4b5489-2079-40b9-bd77-6e1bf90bc19f");
        private static readonly Guid EmployeeManagement = Guid.Parse("81ab8a87-8ccd-4015-a917-0627cee6a100");
        private static readonly Guid AttendanceManagement = Guid.Parse("52c9cf54-1eb2-44d2-81bb-524cf29c0a94");
        private static readonly Guid MastersMangent = Guid.Parse("be3b3afc-6ccf-4566-b9b6-aafcb65546be");
        private static readonly Guid DirectoryManagement = Guid.Parse("39e66f81-efc6-446c-95bd-46bff6cfb606");
        private static readonly Guid TenantManagement = Guid.Parse("2f3509b7-160d-410a-b9b6-daadd96c986d");

        public AppMenuController(UserHelper userHelper,
            SidebarMenuHelper sideBarMenuHelper,
            IMapper mapper,
            ILoggingService logger,
            IServiceScopeFactory serviceScopeFactory)
        {

            _userHelper = userHelper;
            _sideBarMenuHelper = sideBarMenuHelper;
            _mapper = mapper;
            _logger = logger;
            _serviceScopeFactory = serviceScopeFactory;
            tenantId = userHelper.GetTenantId();
        }


        /// <summary>
        /// Creates a new sidebar menu section for the tenant.
        /// Only accessible by root users or for the super tenant.
        /// </summary>
        /// <param name="menuSectionDto">The data for the new menu section.</param>
        /// <returns>HTTP response with result of the operation.</returns>

        [HttpPost("add/sidebar/menu-section")]
        public async Task<IActionResult> CreateAppSideBarMenu([FromBody] CreateMenuSectionDto menuSectionDto)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser || tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: Employee {EmployeeId} attempted to create sidebar menu in Tenant {TenantId}", loggedInEmployee.Id, tenantId);
                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Map DTO to entity
            var sideMenuSection = _mapper.Map<MenuSection>(menuSectionDto);
            sideMenuSection.TenantId = tenantId;

            try
            {
                // Step 4: Save entity using helper
                sideMenuSection = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenuSection);

                if (sideMenuSection == null)
                {
                    _logger.LogWarning("Failed to create sidebar menu section. Tenant: {TenantId}, Request: {@MenuSectionDto}", tenantId, menuSectionDto);
                    return BadRequest(ApiResponse<object>.ErrorResponse("Invalid MenuSection", 400));
                }

                // Step 5: Log success
                _logger.LogInfo("Sidebar menu created successfully. SectionId: {SectionId}, TenantId: {TenantId}, EmployeeId: {EmployeeId}",
                    sideMenuSection.Id, tenantId, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(sideMenuSection, "Sidebar menu created successfully.", 201));
            }
            catch (Exception ex)
            {
                // Step 6: Handle and log unexpected server errors
                _logger.LogError(ex, "Unexpected error occurred while creating sidebar menu. Tenant: {TenantId}, EmployeeId: {EmployeeId}, Request: {@MenuSectionDto}",
                    tenantId, loggedInEmployee.Id, menuSectionDto);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred.", 500));
            }
        }

        /// <summary>
        /// Updates an existing sidebar menu section for the tenant.
        /// Only accessible by root users or for the super tenant.
        /// </summary>
        /// <param name="sectionId">The unique identifier of the section to update.</param>
        /// <param name="updatedSection">The updated data for the sidebar menu section.</param>
        /// <returns>HTTP response with the result of the operation.</returns>

        [HttpPut("edit/sidebar/menu-section/{sectionId}")]
        public async Task<IActionResult> UpdateMenuSection(Guid sectionId, [FromBody] UpdateMenuSectionDto updatedSection)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser && tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: User {UserId} attempted to update sidebar menu section {SectionId} in Tenant {TenantId}",
                    loggedInEmployee.Id, sectionId, tenantId);

                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Validate request
            if (sectionId == Guid.Empty || sectionId != updatedSection.Id)
            {
                _logger.LogWarning("Invalid update request. Tenant: {TenantId}, SectionId: {SectionId}, PayloadId: {PayloadId}, UserId: {UserId}",
                    tenantId, sectionId, updatedSection.Id, loggedInEmployee.Id);

                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID or mismatched payload.", 400));
            }

            // Step 4: Map DTO to entity
            var menuSectionEntity = _mapper.Map<MenuSection>(updatedSection);

            try
            {
                // Step 5: Perform update operation
                var result = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, menuSectionEntity);

                if (result == null)
                {
                    _logger.LogWarning("Menu section not found for update. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
                        sectionId, tenantId, loggedInEmployee.Id);
                    return NotFound(ApiResponse<object>.ErrorResponse("Menu section not found", 404));
                }

                // Step 6: Successful update
                _logger.LogInfo("Menu section updated successfully. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
                    sectionId, tenantId, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(result, "Menu section updated successfully"));
            }
            catch (Exception ex)
            {
                // Step 7: Unexpected server error
                _logger.LogError(ex, "Failed to update menu section. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}, Payload: {@UpdatedSection}",
                    sectionId, tenantId, loggedInEmployee.Id, updatedSection);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server error", "An unexpected error occurred while updating the menu section.", 500));
            }
        }

        /// <summary>
        /// Adds a new menu item to an existing sidebar menu section.
        /// Only accessible by root users or for the super tenant.
        /// </summary>
        /// <param name="sectionId">The unique identifier of the section the item will be added to.</param>
        /// <param name="newItemDto">The details of the new menu item.</param>
        /// <returns>HTTP response with the result of the operation.</returns>

        [HttpPost("add/sidebar/menus/{sectionId}/items")]
        public async Task<IActionResult> AddMenuItem(Guid sectionId, [FromBody] CreateMenuItemDto newItemDto)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser && tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: User {UserId} attempted to add menu item to section {SectionId} in Tenant {TenantId}",
                    loggedInEmployee.Id, sectionId, tenantId);

                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Input validation
            if (sectionId == Guid.Empty || newItemDto == null)
            {
                _logger.LogWarning("Invalid AddMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, UserId: {UserId}",
                    tenantId, sectionId, loggedInEmployee.Id);

                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID or menu item payload.", 400));
            }

            try
            {
                // Step 4: Map DTO to entity
                var menuItemEntity = _mapper.Map<MenuItem>(newItemDto);

                // Step 5: Perform Add operation
                var result = await _sideBarMenuHelper.AddMenuItemAsync(sectionId, menuItemEntity);

                if (result == null)
                {
                    _logger.LogWarning("Menu section not found. Unable to add menu item. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
                        sectionId, tenantId, loggedInEmployee.Id);

                    return NotFound(ApiResponse<object>.ErrorResponse("Menu section not found", 404));
                }

                // Step 6: Successful addition
                _logger.LogInfo("Menu item added successfully. SectionId: {SectionId}, MenuItemId: {MenuItemId}, TenantId: {TenantId}, UserId: {UserId}",
                    sectionId, result.Id, tenantId, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(result, "Menu item added successfully"));
            }
            catch (Exception ex)
            {
                // Step 7: Handle unexpected errors
                _logger.LogError(ex, "Error occurred while adding menu item. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}, Payload: {@NewItemDto}",
                    sectionId, tenantId, loggedInEmployee.Id, newItemDto);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server error", "An unexpected error occurred while adding the menu item.", 500));
            }
        }

        /// <summary>
        /// Updates an existing menu item inside a sidebar menu section.
        /// Only accessible by root users or within the super tenant.
        /// </summary>
        /// <param name="sectionId">The ID of the sidebar menu section.</param>
        /// <param name="itemId">The ID of the menu item to update.</param>
        /// <param name="updatedMenuItem">The updated menu item details.</param>
        /// <returns>HTTP response with the result of the update operation.</returns>

        [HttpPut("edit/sidebar/{sectionId}/items/{itemId}")]
        public async Task<IActionResult> UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] UpdateMenuItemDto updatedMenuItem)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser && tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: User {UserId} attempted to update menu item {ItemId} in Section {SectionId}, Tenant {TenantId}",
                    loggedInEmployee.Id, itemId, sectionId, tenantId);

                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Input validation
            if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null || updatedMenuItem.Id != itemId)
            {
                _logger.LogWarning("Invalid UpdateMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, loggedInEmployee.Id);

                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400));
            }

            // Step 4: Map DTO to entity
            var menuItemEntity = _mapper.Map<MenuItem>(updatedMenuItem);

            try
            {
                // Step 5: Perform update operation
                var result = await _sideBarMenuHelper.UpdateMenuItemAsync(sectionId, itemId, menuItemEntity);

                if (result == null)
                {
                    _logger.LogWarning("Menu item not found or update failed. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
                        tenantId, sectionId, itemId, loggedInEmployee.Id);
                    return NotFound(ApiResponse<object>.ErrorResponse("Menu item not found or update failed.", 404));
                }

                // Step 6: Success log
                _logger.LogInfo("Menu item updated successfully. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(result, "Sidebar menu item updated successfully."));
            }
            catch (Exception ex)
            {
                // ✅ Step 7: Handle server errors
                _logger.LogError(ex, "Error occurred while updating menu item. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}, Payload: {@UpdatedMenuItem}",
                    tenantId, sectionId, itemId, loggedInEmployee.Id, updatedMenuItem);

                return StatusCode(
                    500,
                    ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while updating the menu item.", 500)
                );
            }
        }

        /// <summary>
        /// Adds a new sub-menu item to an existing menu item inside a sidebar menu section.
        /// Only accessible by root users or within the super tenant.
        /// </summary>
        /// <param name="sectionId">The ID of the sidebar menu section.</param>
        /// <param name="itemId">The ID of the parent menu item.</param>
        /// <param name="newSubItem">The details of the new sub-menu item.</param>
        /// <returns>HTTP response with the result of the add operation.</returns>

        [HttpPost("add/sidebar/menus/{sectionId}/items/{itemId}/subitems")]
        public async Task<IActionResult> AddSubMenuItem(Guid sectionId, Guid itemId, [FromBody] CreateSubMenuItemDto newSubItem)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser && tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: User {UserId} attempted to add sub-menu item in Section {SectionId}, MenuItem {ItemId}, Tenant {TenantId}",
                    loggedInEmployee.Id, sectionId, itemId, tenantId);

                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Validate input
            if (sectionId == Guid.Empty || itemId == Guid.Empty || newSubItem == null)
            {
                _logger.LogWarning("Invalid AddSubMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, loggedInEmployee.Id);

                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, item ID, or sub-menu item payload.", 400));
            }

            try
            {
                // Step 4: Map DTO to entity
                var subMenuItemEntity = _mapper.Map<SubMenuItem>(newSubItem);

                // Step 5: Perform add operation
                var result = await _sideBarMenuHelper.AddSubMenuItemAsync(sectionId, itemId, subMenuItemEntity);

                if (result == null)
                {
                    _logger.LogWarning("Parent menu item not found. Failed to add sub-menu item. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
                        tenantId, sectionId, itemId, loggedInEmployee.Id);

                    return NotFound(ApiResponse<object>.ErrorResponse("Parent menu item not found.", 404));
                }

                // Step 6: Success logging
                _logger.LogInfo("Sub-menu item added successfully. Tenant: {TenantId}, SectionId: {SectionId}, ParentItemId: {ItemId}, SubItemId: {SubItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, result.Id, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(result, "Sub-menu item added successfully."));
            }
            catch (Exception ex)
            {
                // Step 7: Handle unexpected errors
                _logger.LogError(ex, "Error occurred while adding sub-menu item. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}, Payload: {@NewSubItem}",
                    tenantId, sectionId, itemId, loggedInEmployee.Id, newSubItem);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while adding the sub-menu item.", 500));
            }
        }

        /// <summary>
        /// Updates an existing sub-menu item inside a sidebar menu section.
        /// Only accessible by root users or within the super tenant.
        /// </summary>
        /// <param name="sectionId">The ID of the sidebar menu section.</param>
        /// <param name="itemId">The ID of the parent menu item.</param>
        /// <param name="subItemId">The ID of the sub-menu item to update.</param>
        /// <param name="updatedSubMenuItem">The updated sub-menu item details.</param>
        /// <returns>HTTP response with the result of the update operation.</returns>

        [HttpPut("edit/sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")]
        public async Task<IActionResult> UpdateSubmenuItem(Guid sectionId, Guid itemId, Guid subItemId, [FromBody] UpdateSubMenuItemDto updatedSubMenuItem)
        {
            // Step 1: Fetch logged-in user
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;

            // Step 2: Authorization check
            if (!isRootUser && tenantId != superTenantId)
            {
                _logger.LogWarning("Access denied: User {UserId} attempted to update sub-menu {SubItemId} under MenuItem {ItemId} in Section {SectionId}, Tenant {TenantId}",
                    loggedInEmployee.Id, subItemId, itemId, sectionId, tenantId);

                return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
            }

            // Step 3: Input validation
            if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem == null || updatedSubMenuItem.Id != subItemId)
            {
                _logger.LogWarning("Invalid UpdateSubMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, SubItemId: {SubItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, subItemId, loggedInEmployee.Id);

                return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, menu item ID, sub-item ID, or payload mismatch.", 400));
            }

            try
            {
                // Step 4: Map DTO to entity
                var subMenuEntity = _mapper.Map<SubMenuItem>(updatedSubMenuItem);

                // Step 5: Perform update operation
                var result = await _sideBarMenuHelper.UpdateSubmenuItemAsync(sectionId, itemId, subItemId, subMenuEntity);

                if (result == null)
                {
                    _logger.LogWarning("Sub-menu item not found or update failed. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, SubItemId: {SubItemId}, UserId: {UserId}",
                        tenantId, sectionId, itemId, subItemId, loggedInEmployee.Id);

                    return NotFound(ApiResponse<object>.ErrorResponse("Sub-menu item not found.", 404));
                }

                // Step 6: Log success
                _logger.LogInfo("Sub-menu item updated successfully. Tenant: {TenantId}, SectionId: {SectionId}, MenuItemId: {ItemId}, SubItemId: {SubItemId}, UserId: {UserId}",
                    tenantId, sectionId, itemId, subItemId, loggedInEmployee.Id);

                return Ok(ApiResponse<object>.SuccessResponse(result, "Sub-menu item updated successfully."));
            }
            catch (Exception ex)
            {
                // Step 7: Handle unexpected errors
                _logger.LogError(ex, "Error occurred while updating sub-menu item. Tenant: {TenantId}, SectionId: {SectionId}, MenuItemId: {ItemId}, SubItemId: {SubItemId}, UserId: {UserId}, Payload: {@UpdatedSubMenuItem}",
                    tenantId, sectionId, itemId, subItemId, loggedInEmployee.Id, updatedSubMenuItem);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while updating the sub-menu item.", 500));
            }
        }

        /// <summary>
        /// Fetches the sidebar menu for the current tenant and filters items based on employee permissions.
        /// </summary>
        /// <returns>The sidebar menu with only the items/sub-items the employee has access to.</returns>

        [HttpGet("get/menu")]
        public async Task<IActionResult> GetAppSideBarMenu()
        {
            // Step 1: Get logged-in employee
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var employeeId = loggedInEmployee.Id;

            using var scope = _serviceScopeFactory.CreateScope();
            var _permissions = scope.ServiceProvider.GetRequiredService<PermissionServices>();

            try
            {
                // Step 2: Fetch all menu sections for the tenant
                var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(tenantId);

                if (!(menus?.Any() ?? false))
                {
                    menus = new List<MenuSection>
                    {
                        MenuStaticMaster.menu
                    };
                }

                foreach (var menu in menus)
                {
                    var allowedItems = new List<MenuItem>();

                    foreach (var item in menu.Items)
                    {
                        // --- Item permission check ---
                        if (!item.PermissionIds.Any())
                        {
                            allowedItems.Add(item);
                        }
                        else
                        {
                            // Convert permission string IDs to GUIDs
                            var menuPermissionIds = item.PermissionIds
                                .Select(Guid.Parse)
                                .ToList();

                            bool isAllowed = await _permissions.HasPermissionAny(menuPermissionIds, employeeId);

                            // If allowed, filter its submenus as well
                            if (isAllowed)
                            {
                                if (item.Submenu?.Any() == true)
                                {
                                    var allowedSubmenus = new List<SubMenuItem>();

                                    foreach (var subItem in item.Submenu)
                                    {
                                        if (!subItem.PermissionIds.Any())
                                        {
                                            allowedSubmenus.Add(subItem);
                                            continue;
                                        }

                                        var subMenuPermissionIds = subItem.PermissionIds
                                            .Select(Guid.Parse)
                                            .ToList();

                                        bool isSubItemAllowed = await _permissions.HasPermissionAny(subMenuPermissionIds, employeeId);

                                        if (isSubItemAllowed)
                                        {
                                            allowedSubmenus.Add(subItem);
                                        }
                                    }

                                    // Replace with filtered submenus
                                    item.Submenu = allowedSubmenus;
                                }

                                allowedItems.Add(item);
                            }
                        }
                    }

                    // Replace with filtered items
                    menu.Items = allowedItems;
                }

                // Step 3: Log success
                _logger.LogInfo("Fetched sidebar menu successfully. Tenant: {TenantId}, EmployeeId: {EmployeeId}, SectionsReturned: {Count}",
                    tenantId, employeeId, menus.Count);

                var response = _mapper.Map<List<MenuSectionVM>>(menus);
                return Ok(ApiResponse<object>.SuccessResponse(response, "Sidebar menu fetched successfully"));
            }
            catch (Exception ex)
            {
                // Step 4: Handle unexpected errors
                _logger.LogError(ex, "Error occurred while fetching sidebar menu. Tenant: {TenantId}, EmployeeId: {EmployeeId}",
                    tenantId, employeeId);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while fetching the sidebar menu.", 500));
            }
        }

        /// <summary>
        /// Retrieves the master menu list based on enabled features for the current tenant.
        /// </summary>
        /// <returns>List of master menu items available for the tenant</returns>

        [HttpGet("get/master-list")]
        public async Task<IActionResult> GetMasterList()
        {
            // Start logging scope for observability

            try
            {
                // Get currently logged-in employee
                var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
                _logger.LogInfo("Fetching master list for EmployeeId: {EmployeeId}", loggedInEmployee.Id);

                using var scope = _serviceScopeFactory.CreateScope();
                var generalHelper = scope.ServiceProvider.GetRequiredService<GeneralHelper>();

                // Define static master menus for each feature section
                var featureMenus = new Dictionary<Guid, List<MasterMenuVM>>
                {
                    {
                        EmployeeManagement, new List<MasterMenuVM>
                        {
                            new MasterMenuVM { Id = 1, Name = "Application Role" },
                            new MasterMenuVM { Id = 2, Name = "Job Role" },
                            new MasterMenuVM { Id = 9, Name = "Document Category" },
                            new MasterMenuVM { Id = 10, Name = "Document Type" }
                        }
                    },
                    {
                        ProjectManagement, new List<MasterMenuVM>
                        {
                            new MasterMenuVM { Id = 3, Name = "Work Category" },
                            new MasterMenuVM { Id = 8, Name = "Services" }
                        }
                    },
                    {
                        DirectoryManagement, new List<MasterMenuVM>
                        {
                            new MasterMenuVM { Id = 4, Name = "Contact Category" },
                            new MasterMenuVM { Id = 5, Name = "Contact Tag" }
                        }
                    },
                    {
                        ExpenseManagement, new List<MasterMenuVM>
                        {
                            new MasterMenuVM { Id = 6, Name = "Expense Type" },
                            new MasterMenuVM { Id = 7, Name = "Payment Mode" },
                            new MasterMenuVM { Id = 10, Name = "Payment Adjustment Head" }
                        }
                    }
                };

                if (tenantId == superTenantId)
                {
                    var superResponse = featureMenus.Values.SelectMany(list => list).OrderBy(r => r.Name).ToList();

                    _logger.LogInfo("MasterMenu count for TenantId {TenantId}: {Count}", tenantId, superResponse.Count);
                    return Ok(ApiResponse<object>.SuccessResponse(superResponse, "Successfully fetched the master table list", 200));
                }

                // Fetch features enabled for tenant
                var featureIds = await generalHelper.GetFeatureIdsByTenentIdAsync(tenantId);
                _logger.LogInfo("Enabled features for TenantId: {TenantId} -> {FeatureIds}", tenantId, string.Join(",", featureIds));

                // Aggregate menus based on enabled features
                var response = featureIds
                    .Where(id => featureMenus.ContainsKey(id))
                    .SelectMany(id => featureMenus[id])
                    .OrderBy(r => r.Name)
                    .ToList();

                _logger.LogInfo("MasterMenu count for TenantId {TenantId}: {Count}", tenantId, response.Count);
                return Ok(ApiResponse<object>.SuccessResponse(response, "Successfully fetched the master table list", 200));
            }
            catch (Exception ex)
            {
                // Critical error tracking
                _logger.LogError(ex, "Error occurred while fetching master menu list for TenantId: {TenantId}", tenantId);
                return StatusCode(500, ApiResponse<string>.ErrorResponse("An unexpected error occurred while fetching master menu list."));
            }
        }

        [HttpGet("get/menu-mobile")]
        public async Task<IActionResult> GetAppSideBarMenuForobile()
        {
            // Step 1: Get logged-in employee
            var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
            var employeeId = loggedInEmployee.Id;

            using var scope = _serviceScopeFactory.CreateScope();
            var _permissions = scope.ServiceProvider.GetRequiredService<PermissionServices>();

            try
            {
                // Step 2: Fetch all menu sections for the tenant
                var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(tenantId);
                if (!(menus?.Any() ?? false))
                {
                    menus = new List<MenuSection>
                    {
                        MenuStaticMaster.menu
                    };
                }
                List<MenuSectionApplicationVM> response = new List<MenuSectionApplicationVM>();

                foreach (var menu in menus)
                {
                    var allowedItems = new List<MenuItem>();

                    foreach (var item in menu.Items)
                    {
                        // --- Item permission check ---
                        if (!item.PermissionIds.Any())
                        {
                            MenuSectionApplicationVM menuVM = new MenuSectionApplicationVM
                            {
                                Id = item.Id,
                                Name = item.Text,
                                Available = true,
                                MobileLink = item.MobileLink,
                            };
                            response.Add(menuVM);

                            if (item.Submenu?.Any() == true)
                            {
                                var allowedSubmenus = new List<SubMenuItem>();

                                foreach (var subItem in item.Submenu)
                                {
                                    if (!subItem.PermissionIds.Any())
                                    {
                                        MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
                                        {
                                            Id = subItem.Id,
                                            Name = subItem.Text,
                                            Available = true,
                                            MobileLink = subItem.MobileLink
                                        };
                                        response.Add(subMenuVM);
                                        continue;
                                    }

                                    var subMenuPermissionIds = subItem.PermissionIds
                                        .Select(Guid.Parse)
                                        .ToList();

                                    bool isSubItemAllowed = await _permissions.HasPermissionAny(subMenuPermissionIds, employeeId);

                                    if (isSubItemAllowed)
                                    {
                                        MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
                                        {
                                            Id = subItem.Id,
                                            Name = subItem.Text,
                                            Available = true,
                                            MobileLink = subItem.MobileLink
                                        };
                                        response.Add(subMenuVM);
                                    }
                                }

                                // Replace with filtered submenus
                                item.Submenu = allowedSubmenus;
                            }
                        }
                        else
                        {
                            // Convert permission string IDs to GUIDs
                            var menuPermissionIds = item.PermissionIds
                                .Select(Guid.Parse)
                                .ToList();

                            bool isAllowed = await _permissions.HasPermissionAny(menuPermissionIds, employeeId);

                            // If allowed, filter its submenus as well
                            if (isAllowed)
                            {
                                if (item.Submenu?.Any() == true)
                                {
                                    var allowedSubmenus = new List<SubMenuItem>();

                                    foreach (var subItem in item.Submenu)
                                    {
                                        if (!subItem.PermissionIds.Any())
                                        {
                                            MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
                                            {
                                                Id = subItem.Id,
                                                Name = subItem.Text,
                                                Available = true,
                                                MobileLink = subItem.MobileLink
                                            };
                                            response.Add(subMenuVM);
                                            continue;
                                        }

                                        var subMenuPermissionIds = subItem.PermissionIds
                                            .Select(Guid.Parse)
                                            .ToList();

                                        bool isSubItemAllowed = await _permissions.HasPermissionAny(subMenuPermissionIds, employeeId);

                                        if (isSubItemAllowed)
                                        {
                                            MenuSectionApplicationVM subMenuVM = new MenuSectionApplicationVM
                                            {
                                                Id = subItem.Id,
                                                Name = subItem.Text,
                                                Available = true,
                                                MobileLink = subItem.MobileLink,
                                            };
                                            response.Add(subMenuVM);
                                        }
                                    }

                                    // Replace with filtered submenus
                                    item.Submenu = allowedSubmenus;
                                }

                                MenuSectionApplicationVM menuVM = new MenuSectionApplicationVM
                                {
                                    Id = item.Id,
                                    Name = item.Text,
                                    Available = true,
                                    MobileLink = item.MobileLink
                                };
                                response.Add(menuVM);
                            }
                        }
                    }

                    // Replace with filtered items
                    menu.Items = allowedItems;
                }

                var viewDocumentTask = Task.Run(async () =>
                {
                    using var taskScope = _serviceScopeFactory.CreateScope();
                    var permissions = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
                    return await permissions.HasPermission(PermissionsMaster.ViewDocument, employeeId);
                });

                var uploadDocumentTask = Task.Run(async () =>
                {
                    using var taskScope = _serviceScopeFactory.CreateScope();
                    var permissions = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
                    return await permissions.HasPermission(PermissionsMaster.UploadDocument, employeeId);
                });

                var verifyDocumentTask = Task.Run(async () =>
                {
                    using var taskScope = _serviceScopeFactory.CreateScope();
                    var permissions = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
                    return await permissions.HasPermission(PermissionsMaster.VerifyDocument, employeeId);
                });

                var downloadDocumentTask = Task.Run(async () =>
                {
                    using var taskScope = _serviceScopeFactory.CreateScope();
                    var permissions = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
                    return await permissions.HasPermission(PermissionsMaster.DownloadDocument, employeeId);
                });

                await Task.WhenAll(viewDocumentTask, uploadDocumentTask, verifyDocumentTask, downloadDocumentTask);

                var viewDocument = viewDocumentTask.Result;
                var uploadDocument = uploadDocumentTask.Result;
                var verifyDocument = verifyDocumentTask.Result;
                var downloadDocument = downloadDocumentTask.Result;

                if (viewDocument || uploadDocument || verifyDocument || downloadDocument)
                {
                    response.Add(new MenuSectionApplicationVM
                    {
                        Id = Guid.Parse("443d6444-250b-4164-89fd-bcd7cedd9e43"),
                        Name = "Documents",
                        Available = true,
                        MobileLink = "/dashboard/document-main-page"
                    });
                }

                response.Add(new MenuSectionApplicationVM
                {
                    Id = Guid.Parse("7faddfe7-994b-4712-91c2-32ba44129d9b"),
                    Name = "Service Projects",
                    Available = true,
                    MobileLink = "/dashboard/service-projects"
                });

                // Step 3: Log success
                response = response.Where(ms => !string.IsNullOrWhiteSpace(ms.MobileLink)).ToList();
                _logger.LogInfo("Fetched sidebar menu successfully. Tenant: {TenantId}, EmployeeId: {EmployeeId}, SectionsReturned: {Count}",
                    tenantId, employeeId, menus.Count);
                return Ok(ApiResponse<object>.SuccessResponse(response, "Sidebar menu fetched successfully", 200));
            }
            catch (Exception ex)
            {
                // Step 4: Handle unexpected errors
                _logger.LogError(ex, "Error occurred while fetching sidebar menu. Tenant: {TenantId}, EmployeeId: {EmployeeId}",
                    tenantId, employeeId);

                return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while fetching the sidebar menu.", 500));
            }
        }

    }

}

