using MediatR;
using Modules.User.Application.Gateways;

namespace Modules.User.Application.Commands.Access;

public class CreateRoleCommand : IRequest<int>
{
    public string Code { get; init; } = null!;
    public string Name { get; init; } = null!;
    public string? Description { get; init; }
    public IReadOnlyCollection<int> PermissionIds { get; init; } = [];
}

public class CreateRoleCommandHandler(IRoleRepository roleRepository, IPermissionRepository permissionRepository,
    IUnitOfWork uow) : IRequestHandler<CreateRoleCommand, int>
{
    public async Task<int> Handle(CreateRoleCommand request, CancellationToken cancellationToken)
    {
        if (await roleRepository.GetByNameAsync(request.Name, cancellationToken) is not null)
            throw new InvalidOperationException("Role with the same name already exists.");
        
        if (!await permissionRepository.ExistsAllAsync(request.PermissionIds, cancellationToken))
            throw new InvalidOperationException("Some permissions do not exist.");
        
        var role = Domain.Entities.Access.Role.Create(request.Code,request.Name, DateTime.UtcNow, request.PermissionIds);
        if (!string.IsNullOrWhiteSpace(request.Description)) role.SetDescription(request.Description);
        await roleRepository.AddAsync(role, cancellationToken);
        await uow.SaveChangesAsync(cancellationToken);
        return role.Id;
    }
}