using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Identity;
using Baya.Application.Models.Common;
using Baya.Domain.Entities.User;
using MapsterMapper;
using Mediator;

namespace Baya.Application.Features.Users.Commands.Create;

internal class UserCreateCommandHandler(
    IAppUserManager userManager,
    ISmsSender smsSender,
    IMapper mapper)
    : IRequestHandler<UserCreateCommand, OperationResult<UserCreateCommandResult>>
{
    public async ValueTask<OperationResult<UserCreateCommandResult>> Handle(UserCreateCommand request,
        CancellationToken cancellationToken)
    {
        var userNameExist = await userManager.IsExistUser(request.PhoneNumber);

        if (userNameExist)
            return OperationResult<UserCreateCommandResult>.FailureResult("Phone number already exists");

        var phoneNumberExist = await userManager.IsExistUserName(request.UserName);

        if (phoneNumberExist)
            return OperationResult<UserCreateCommandResult>.FailureResult("Username already exists");

        var user = mapper.Map<User>(request);


            var createResult =string.IsNullOrEmpty(request.Password)?
                await userManager.CreateUser(user)
                :await  userManager.CreateUser(user, request.Password);

        if (!createResult.Succeeded)
        {
            return OperationResult<UserCreateCommandResult>.FailureResult(string.Join(",",
                createResult.Errors.Select(c => c.Description)));
        }

        var code = await userManager.GeneratePhoneNumberConfirmationToken(user, user.PhoneNumber);

        await smsSender.SendOtpAsync(user.PhoneNumber, code, cancellationToken);

        return OperationResult<UserCreateCommandResult>.SuccessResult(new UserCreateCommandResult
            { UserGeneratedKey = user.GeneratedCode });
    }
}