using LiteCqrs;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Common.Models;

namespace TeleWave.Application.Auth.Refresh;

public sealed class RefreshCommandHandler(
    IRefreshTokenService refreshTokenService,
    IIdentityService identityService,
    IJwtTokenService jwtTokenService
) : ICommandHandler<RefreshCommand, Result<AuthResult>>
{
    public async Task<Result<AuthResult>> Handle(
        RefreshCommand command,
        CancellationToken cancellationToken
    )
    {
        var rotated = await refreshTokenService.RotateAsync(command.RawToken, cancellationToken);
        if (!rotated.IsSuccess)
            return Result.Failure<AuthResult>(rotated.Error);

        var profile = await identityService.GetProfileAsync(
            rotated.Value.UserId,
            cancellationToken
        );
        if (profile is null || profile.IsBlocked)
            return Result.Failure<AuthResult>(AuthErrors.Unauthorized);

        var (accessToken, accessExpiresAt) = jwtTokenService.GenerateAccessToken(
            new AuthenticatedUser(profile.Id, profile.UserName, profile.Role)
        );

        var dto = new CurrentUserDto(profile.Id, profile.UserName, profile.Role);
        return Result.Success(
            new AuthResult(
                accessToken,
                accessExpiresAt,
                rotated.Value.RawToken,
                rotated.Value.ExpiresAt,
                dto
            )
        );
    }
}
