using AutoMapper;

using CloudGaming.Code.Account;
using CloudGaming.Code.Cache;
using CloudGaming.Code.Config;
using CloudGaming.Code.DataAccess;
using CloudGaming.DtoModel.Account.User;

using HuanMeng.DotNetCore.JwtInfrastructure.Interface;
using HuanMeng.DotNetCore.Redis;

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;

using StackExchange.Redis;

namespace CloudGaming.Code.AppExtend
{
    /// <summary>
    /// BLL 基础类
    /// </summary>
    public class CloudGamingBase : BLLBase<DAO>
    {
        public CloudGamingBase(IServiceProvider serviceProvider) : base(serviceProvider)
        {
        }

        #region 数据库
        private DAO _dao;
        /// <summary>
        /// DAO 数据库
        /// </summary>
        public override DAO Dao
        {
            get
            {
                if (_dao == null)
                {
                    _dao = new DAO(_serviceProvider);
                }
                return _dao;
            }
        }
        #endregion

        #region 映射
        private IMapper _mapper;
        /// <summary>
        /// DTO 映射
        /// </summary>
        public virtual IMapper Mapper
        {
            get
            {
                if (_mapper == null)
                {
                    _mapper = _serviceProvider.GetRequiredService<IMapper>();
                }
                return _mapper;
            }
            set
            {
                _mapper = value;
            }
        }
        #endregion

        #region AppConfig 配置
        private AppConfig _appConfig;
        /// <summary>
        /// AppConfig 配置
        /// </summary>
        public AppConfig AppConfig
        {
            get
            {
                if (_appConfig == null)
                {
                    _appConfig = _serviceProvider.GetRequiredService<AppConfig>();
                }
                return _appConfig;
            }
        }
        #endregion

        #region 请求信息
        private IHttpContextAccessor _httpContextAccessor;
        /// <summary>
        /// HttpContextAccessor
        /// </summary>
        public IHttpContextAccessor HttpContextAccessor
        {
            get
            {
                if (_httpContextAccessor == null)
                {
                    _httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
                }
                return _httpContextAccessor;
            }
        }
        #endregion

        #region HTTP 请求
        private IHttpClientFactory _httpClientFactory;
        /// <summary>
        /// HttpClientFactory
        /// </summary>
        public IHttpClientFactory HttpClientFactory
        {
            get
            {
                if (_httpClientFactory == null)
                {
                    _httpClientFactory = _serviceProvider.GetRequiredService<IHttpClientFactory>();
                }
                return _httpClientFactory;
            }
        }
        #endregion

        #region JWT 管理
        private IJwtAuthManager _jwtAuthManager;
        /// <summary>
        /// JWT 管理
        /// </summary>
        public IJwtAuthManager JwtAuthManager
        {
            get
            {
                if (_jwtAuthManager == null)
                {
                    _jwtAuthManager = _serviceProvider.GetService<IJwtAuthManager>();
                }
                return _jwtAuthManager;
            }
        }
        #endregion

        #region 日志
        private ILogger<CloudGamingBase> _logger;
        /// <summary>
        /// 日志
        /// </summary>
        public ILogger<CloudGamingBase> Logger
        {
            get
            {
                if (_logger == null)
                {
                    _logger = _serviceProvider.GetRequiredService<ILogger<CloudGamingBase>>();
                }
                return _logger;
            }
        }
        #endregion

        #region Redis
        private IDatabase _redis;
        /// <summary>
        /// Redis 缓存
        /// </summary>
        public IDatabase RedisCache
        {
            get
            {
                if (_redis == null)
                {
                    _redis = RedisConnection.GetRedis(AppConfig.RedisConnectionString);
                }
                return _redis;
            }
        }
        private IServer _redisServer;
        /// <summary>
        /// 数据库查询
        /// </summary>
        public IServer RedisServerCache
        {
            get
            {
                if (_redisServer == null)
                {
                    _redisServer = RedisConnection.GetServer(AppConfig.RedisConnectionString);
                }
                return _redisServer;
            }
        }
        #endregion

        #region 缓存
        private CloudGamingCache _cache;
        /// <summary>
        /// 缓存
        /// </summary>
        public CloudGamingCache Cache
        {
            get
            {
                if (_cache == null)
                {
                    _cache = new CloudGamingCache(this);
                }
                return _cache;
            }
        }
        #endregion

        #region app配置
        private AppRequestConfig appRequestInfo;
        /// <summary>
        /// app请求配置
        /// </summary>
        public AppRequestConfig AppRequestInfo
        {
            get
            {
                if (appRequestInfo == null)
                {
                    appRequestInfo = new AppRequestConfig(HttpContextAccessor?.HttpContext?.Request);
                }
                return appRequestInfo;
            }
        }

        private bool? isChecking;
        /// <summary>
        /// 是否在审核模式中
        /// </summary>
        public bool IsChecking
        {
            get
            {
                if (isChecking == null)
                {
                    string key = $"App:Config:{AppRequestInfo.Platform}:{AppRequestInfo.Channel}:{AppRequestInfo.Version}";
                    isChecking = RedisCache.StringGet<bool?>(key);
                    if (isChecking == null)
                    {
                        isChecking = new AppConfigBLL(this._serviceProvider).GetAppIsChecking();
                        RedisCache.StringSet(key, isChecking, new TimeSpan(1, 0, 0));
                    }

                }
                return isChecking ?? false;
            }
        }
        #endregion

        #region 用户信息
        private RequestUserInfo? _requestUserInfo;
        /// <summary>
        /// 用户信息
        /// </summary>
        public RequestUserInfo RequestUserInfo
        {
            get
            {
                if (_requestUserInfo == null)
                {
                    var accessToken = HttpContextAccessor.HttpContext.Request.Headers.GetAuthorization();
                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        try
                        {
                            var (principal, jwtToken) = JwtAuthManager.DecodeJwtToken(accessToken);
                            if (jwtToken == null)//|| !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)
                            {
                                throw new SecurityTokenException("无效的token");
                            }
                            var userIdStr = principal.FindFirst("UserId")?.Value;
                            if (string.IsNullOrEmpty(userIdStr))
                            {
                                throw new SecurityTokenException("无效的token");
                            }
                            var nickName = principal.FindFirst("NickName")?.Value;
                            var userId = int.Parse(userIdStr);
                            this._requestUserInfo = new RequestUserInfo()
                            {
                                UserId = userId,
                                NickName = nickName
                            };
                        }
                        catch (Exception)
                        {
                            _requestUserInfo = new RequestUserInfo()
                            {
                                UserId = 0
                            };
                        }
                    }
                    else
                    {
                        _requestUserInfo = new RequestUserInfo()
                        {
                            UserId = 0
                        };
                    }
                }

                return _requestUserInfo;
            }
        }

        /// <summary>
        /// 用户Id
        /// </summary>
        public int _UserId
        {
            get
            {
                return RequestUserInfo?.UserId ?? 0;
            }
        }

        private UserInfoCache _userInfo;
        /// <summary>
        /// 用户信息
        /// </summary>
        public UserInfoCache UserInfo
        {
            get
            {
                if (_userInfo == null)
                {
                    if (_UserId == 0)
                    {
                        _userInfo = new UserInfoCache();
                    }

                    _userInfo = _userInfo.GetUserInfo(_UserId, this).Result ?? new UserInfoCache();
                }
                return _userInfo;
            }
        }

        public async Task<UserInfoCache> GetUserInfoCache()
        {
            if (_UserId == 0)
            {
                _userInfo = new UserInfoCache();
            }
            if (_userInfo == null)
            {
                _userInfo = await _userInfo.GetUserInfo(_UserId, this) ?? new UserInfoCache();
            }
            return _userInfo;
        }
        #endregion

        /// <summary>
        /// 创建异常
        /// </summary>
        public Exception CreateException(ResponseCode errorCode, string message)
        {
            return MessageBox.Show(errorCode, message);
        }
    }
}
