using Application.Abstractions.Messaging;
﻿using Application.Abstractions.Identity;
using SharedKernel.Constants;
using System.Data;

namespace Application.Features.Director.Role.Permissions.Get
{
    public sealed class Handler(IIdentityRoleReader roleReader) : IQueryHandler<Query, Response>
    {
        public async Task<Response> Handle(Query request, CancellationToken ct)
        {
            var roleAndClaims = await roleReader.GetRoleAsync(request.RoleID, ct);
            if (roleAndClaims is null)
            {
                throw new DataException($"Role with ID '{request.RoleID}' not found.");
            }

            string[] DefaultActions = { "Create", "View", "Edit", "Delete" };
            var groups = new List<Response.PermissionGroup>();
            var menus = Menus.GetMenus();

            void Traverse(Menu menu, string? parentName = null)
            {
                var fullGroupName = string.IsNullOrWhiteSpace(parentName) ? menu.Name : $"{parentName} - {menu.Name}";
                var fullName = string.IsNullOrWhiteSpace(parentName) ? $"{menu.Name}.{menu.Id}" : $"{parentName} - {menu.Name}.{menu.Id}";

                // 권한 그룹 생성
                if (!string.IsNullOrWhiteSpace(menu.Path) || (menu.Children != null && menu.Children.Count > 0))
                {
                    groups.Add(new Response.PermissionGroup
                    {
                        GroupName = fullGroupName,
                        Permissions = [..DefaultActions.Select(action =>
                        {
                            var permission = $"Permissions.{fullName}.{action}";

                            return new Response.PermissionGroup.Checkbox {
                                DisplayValue = permission,
                                IsSelected = roleAndClaims.Claims.Contains(permission)
                            };
                        })]
                    });
                }

                if (menu.Children != null)
                {
                    foreach (var child in menu.Children)
                    {
                        Traverse(child, menu.Name);
                    }
                }
            }

            foreach (var menu in menus)
            {
                Traverse(menu);
            }

            return new Response {
                RoleID = roleAndClaims.ID,
                RoleName = roleAndClaims.Name,
                RoleClaims = groups
            };
        }
    }
}