using MapsterMapper;
using Microsoft.Extensions.DependencyInjection;

namespace NewRock.Sdk.Security
{
    public interface IAuthorizeGenerator
    {
        NewRockAuthorize GetAuthorize(string key, int expired);
    }

    public class AuthorizeGenerator : IAuthorizeGenerator
    {
        private readonly IServiceScopeFactory _serviceScopeFactory;
        private CreationNewRockAuthorize? _creationAuthorize;

        public AuthorizeGenerator(IServiceScopeFactory serviceScopeFactory)
        {
            _serviceScopeFactory = serviceScopeFactory;
        }


        public NewRockAuthorize GetAuthorize(string key, int expired)
        {
            using var scope = _serviceScopeFactory.CreateScope();
            //var options = scope.ServiceProvider.GetService<IOptionsSnapshot<NewRockConfiguration>>();
            var mapper = scope.ServiceProvider.GetService<IMapper>();
            //var key = options.Value.ReceiveKey;

            if (_creationAuthorize == null)
            {
                var authorize = GenerateAuthorize(key);
                _creationAuthorize = mapper.Map<CreationNewRockAuthorize>(authorize);
                return authorize;
            }

            // 检查过期时间
            //var expired = options.Value.Expired;
            if ((DateTime.Now - _creationAuthorize.CreationTime).TotalSeconds + 5 >= expired)
            {
                _creationAuthorize = mapper.Map<CreationNewRockAuthorize>(GenerateAuthorize(key));
            }

            return mapper.Map<NewRockAuthorize>(_creationAuthorize);
        }

        /// <summary>
        /// 生成一个校验信息
        /// </summary>
        /// <returns></returns>
        private NewRockAuthorize GenerateAuthorize(string key)
        {
            var nonce = Encryptor.GenerateRandomNumber();
            var timestamp = Encryptor.GenerateTimestamp();
            var signature = Encryptor.Signature(key, nonce, timestamp);
            return new NewRockAuthorize
            {
                Nonce = nonce,
                Timestamp = timestamp,
                Signature = signature
            };
        }
    }
}
