namespace CMSMicroservice.Application.UserCQ.Queries.AdminGetJwtToken;

public class AdminGetJwtTokenQueryHandler : IRequestHandler<AdminGetJwtTokenQuery, AdminGetJwtTokenResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IGenerateJwtToken _generateJwt;
    private readonly IHashService _hashService;

    public AdminGetJwtTokenQueryHandler(IApplicationDbContext context, IGenerateJwtToken generateJwt,
        IHashService hashService)
    {
        _context = context;
        _generateJwt = generateJwt;
        _hashService = hashService;
    }

    public async Task<AdminGetJwtTokenResponseDto> Handle(AdminGetJwtTokenQuery request,
        CancellationToken cancellationToken)
    {
        var user = await _context.Users
            .Include(u => u.UserContracts)
            .ThenInclude(u => u.Contract)
            .Include(u => u.UserRoles)
            .ThenInclude(ur => ur.Role)
            .Include(u => u.ClubMembership)
            .FirstOrDefaultAsync(f => f.Mobile == request.Username, cancellationToken);
        if (user == null)
            throw new Exception("Invalid username or password.");

        if (user.UserRoles.All(a => a.RoleId != 2))
            throw new Exception("You do not have permission to do that.");

        // verify password (supports PBKDF2 or legacy SHA-256)
        if (!_hashService.VerifyPassword(request.Password, user.HashPassword))
            throw new Exception("Invalid username or password.");

        return new AdminGetJwtTokenResponseDto()
        {
            Token = await _generateJwt.GenerateJwtToken(user,15),
        };
    }
}