using Microsoft.Extensions.Localization;
using ERP.Core.Dto;
using ERP.Core.Entity;
using ERP.Core.Enum;
using ERP.Core.Repository;
using ERP.Core.Resource;
using ERP.Framework.Cache;
using ERP.Framework.Config;
using ERP.Framework.Constants;
using ERP.Framework.Utils;

namespace ERP.Core.Service
{
    public class AuthService
    {
        private readonly IStringLocalizer<AuthI18N> _localizer;
        private readonly SysUserRepository _sysUserRepository;

        public AuthService(IStringLocalizer<AuthI18N> localizer, SysUserRepository sysUserRepository)
        {
            _localizer = localizer;
            _sysUserRepository = sysUserRepository;
        }

        /// <summary>
        /// 获取登录用户
        /// </summary>
        /// <param name="securityConfig">设置</param>r
        /// <param name="loginName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="deviceKey">设备唯一值</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public  LoginUser GetLoginUser(
            SecurityConfig securityConfig
            , string loginName
            , string password)
        {
            var user = _sysUserRepository.FirstOrDefault(t => t.UserName == loginName);

            if (user == null)
            {
                throw new Exception(string.Format(_localizer["User.NotExist"], loginName));
            }

            CheckUserStatus(user);

            CheckLogin(securityConfig, password, user);

            return new LoginUser();
        }

        private void CheckUserStatus(SysUser user)
        {
            if (user.UserStatus == StatusEnum.Enable)
            {
                return;
            }
            else if (user.UserStatus == StatusEnum.Disable)
            {
                throw new Exception(string.Format(_localizer["User.Bloked"], user.UserName));
            }
        }

        private void CheckLogin(SecurityConfig securityConfig, string password, SysUser loginUser)
        {
            var passwordErrorRedisKey = AuthConstant.PasswordError + IPUtil.GetClientIp();
            var errorNumber = RedisHelper.Get(passwordErrorRedisKey);
            var hasErrorRedis = !errorNumber.IsNullOrEmpty();

            if (hasErrorRedis && errorNumber.ToInt() >= securityConfig.MaxRetryCount)
            {
                // Todo 记录登录信息(超出限制期间登录)
                throw new Exception(string.Format(_localizer["User.Password.RetryLimitExceed"], errorNumber, securityConfig.LockTime));
            }

            var isLogin = CryptoUtil.BCValify(password, loginUser.Password);

            if (!isLogin)
            {
                if (!hasErrorRedis)
                {
                    RedisHelper.SaveExpire(passwordErrorRedisKey, AuthConstant.FirstPasswordError, securityConfig.LockTime);
                }
                else
                {
                    var number = int.Parse(errorNumber) + 1;
                    RedisHelper.Save(passwordErrorRedisKey, number.ToString());
                }

                throw new Exception(_localizer["User.Password.Error"]);
            }

            if (hasErrorRedis)
            {
                RedisHelper.Delete(passwordErrorRedisKey);
            }
        }
    }
}