using Application.Abstractions.Identity;
using Application.Abstractions.Identity.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Persistence.Identity;

public sealed class IdentityRoleReader(RoleManager<IdentityRole> roleManager) : IIdentityRoleReader
{
    public async Task<List<RoleDto>> GetRolesAsync(CancellationToken ct)
    {
        var roles = await roleManager.Roles.AsNoTracking().ToListAsync(ct);
        var list = new List<RoleDto>(roles.Count);

        foreach (var role in roles)
        {
            var claims = await roleManager.GetClaimsAsync(role);

            list.Add(new RoleDto
            {
                ID = role.Id,
                Name = role.Name,
                Claims = [..claims.Select(c => c.Value)]
            });
        }

        return list;
    }

    public async Task<RoleDto> GetRoleAsync(string roleID, CancellationToken ct)
    {
        if (string.IsNullOrWhiteSpace(roleID))
        {
            throw new InvalidOperationException("RoleID는 필수입니다.");
        }

        var role = await roleManager.FindByIdAsync(roleID);
        if (role is null)
        {
            throw new InvalidOperationException($"{roleID} 권한은 존재하지 않습니다.");
        }

        var claims = await roleManager.GetClaimsAsync(role);
        var values = claims.Select(c => c.Value).ToList();

        return new RoleDto{
            ID = role.Id,
            Name = role.Name ?? string.Empty,
            Claims = values
        };
    }
}