using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using DamageAssesment.Api.UsersAccess.Db;
using DamageAssesment.Api.UsersAccess.Interfaces;
using DamageAssesment.Api.UsersAccess.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;

namespace DamageAssesment.Api.UsersAccess.Services
{
    public class TokenServiceProvider : ITokenServiceProvider
    {
        private readonly UsersAccessDbContext usersAccessDbContext;
        private readonly JwtSettings jwtSettings;
        public TokenServiceProvider(IOptions<JwtSettings> options, UsersAccessDbContext usersAccessDbContext)
        {
            this.usersAccessDbContext = usersAccessDbContext;
            this.jwtSettings = options.Value;
        }
        public async Task<string> GenerateToken(Models.User user)
        {
            var randomnumber = new byte[32];
            using (var ramdomnumbergenerator = RandomNumberGenerator.Create())
            {
                ramdomnumbergenerator.GetBytes(randomnumber);
                string refreshtoken = Convert.ToBase64String(randomnumber);
                var token = await usersAccessDbContext.Tokens.FirstOrDefaultAsync(item => item.UserId == user.Id);
                if (token != null)
                {
                    token.RefreshToken = refreshtoken;
                }
                else
                {
                    usersAccessDbContext.Tokens.Add(new Db.Token()
                    {
                        UserId = user.Id,
                        RefreshToken = refreshtoken,
                        IsActive = true
                    });
                }
                await usersAccessDbContext.SaveChangesAsync();

                return refreshtoken;
            }
        }

        public async Task<TokenResponse> TokenAuthenticate(Models.User user, Claim[] claims)
        {
            var token = new JwtSecurityToken(claims: claims, expires: DateTime.Now.AddSeconds(20),
              signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.securitykey)), SecurityAlgorithms.HmacSha256)
            );
            var jwttoken = new JwtSecurityTokenHandler().WriteToken(token);
            return new TokenResponse() { jwttoken = jwttoken, refreshtoken = await GenerateToken(user) };
        }
    }
}