using MediatR;
using Microsoft.AspNetCore.Identity;
using IamService.Domain.AggregatesModel.RoleAggregate;
using IamService.Domain.Exceptions;

namespace IamService.API.Application.Commands.Roles;

/// <summary>
/// EN: Handler for CreateRoleCommand.
/// VI: Handler cho CreateRoleCommand.
/// </summary>
public class CreateRoleCommandHandler : IRequestHandler<CreateRoleCommand, CreateRoleCommandResult>
{
    private readonly RoleManager<ApplicationRole> _roleManager;
    private readonly ILogger<CreateRoleCommandHandler> _logger;

    public CreateRoleCommandHandler(
        RoleManager<ApplicationRole> roleManager,
        ILogger<CreateRoleCommandHandler> logger)
    {
        _roleManager = roleManager;
        _logger = logger;
    }

    public async Task<CreateRoleCommandResult> Handle(CreateRoleCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Creating role: {RoleName}", request.Name);

        // EN: Check if role already exists
        // VI: Kiểm tra role đã tồn tại chưa
        var existingRole = await _roleManager.FindByNameAsync(request.Name);
        if (existingRole != null)
        {
            _logger.LogWarning("Role already exists: {RoleName}", request.Name);
            throw new DomainException($"Role with name '{request.Name}' already exists.");
        }

        // EN: Create new role
        // VI: Tạo role mới
        var role = new ApplicationRole(request.Name, request.Description);

        var result = await _roleManager.CreateAsync(role);

        if (!result.Succeeded)
        {
            var errors = string.Join(", ", result.Errors.Select(e => e.Description));
            _logger.LogError("Failed to create role {RoleName}: {Errors}", request.Name, errors);
            throw new DomainException($"Failed to create role: {errors}");
        }

        _logger.LogInformation("Role {RoleName} created successfully with ID {RoleId}", request.Name, role.Id);

        return new CreateRoleCommandResult(
            role.Id,
            role.Name!,
            role.Description,
            role.CreatedAt);
    }
}
