using Furion.DataEncryption;
using Furion.DependencyInjection;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YBDevice.Application.CommonInfo;
using YBDevice.Entity;

namespace YBDevice.Application
{
    /// <summary>
    /// 账户管理
    /// </summary>
    public class AccountService : IAccountService, ITransient
    {
        private readonly ISqlSugarRepository<YB_Account> repository;
        private readonly SqlSugarClient dbClient;
        private readonly ICommonService _commonService;
        private readonly OperatorModel currentUser;
        public AccountService(ISqlSugarRepository<YB_Account> sqlSugarRepository, ICommonService commonService)
        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _commonService = commonService;
            currentUser = BaseInfoService.GetUserInfo();
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="oldpwd"></param>
        /// <param name="newpwd"></param>
        /// <param name="repwd"></param>
        /// <returns></returns>
        public async Task<ResultInfo> ChangePwdAsync(string oldpwd, string newpwd, string repwd)
        {
            var data = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.Id == currentUser.UserId);
            if (data == null)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "账户未找到" };
            }
            if (newpwd != repwd)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "两次输入密码不一致", data = null };
            }
            var password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(oldpwd, 32).ToLower(), data.Secret).ToLower(), 32).ToLower();
            if (password != data.Password)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "旧密码输入错误", data = null };
            }
            var newpassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(newpwd, 32).ToLower(), data.Secret).ToLower(), 32).ToLower();
            await dbClient.Updateable<YB_Account>().SetColumns(x => new YB_Account
            {
                Password = newpassword
            }).Where(x => x.Id == data.Id).ExecuteCommandAsync();
            return new ResultInfo { code = (int)ResultState.SUCCESS, message = "密码修改成功", data = null };
        }
        /// <summary>
        /// 获取用户资料
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<ResultInfo> GetUserInfo()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 账户登录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> LoginAsync(LoginModel model)
        {
            if (string.IsNullOrEmpty(model.username))
            {
                return new ResultInfo(ResultState.FAIL, "请填写登录账户");
            }
            if (string.IsNullOrEmpty(model.pwd))
            {
                return new ResultInfo(ResultState.FAIL, "请输入密码");
            }
            if (!string.IsNullOrEmpty(model.code))
            {
                var vrcode = WebHelper.GetSession("Elent_session_verifycode");
                if (vrcode.IsEmpty() || Md5.md5(model.code.ToLower(), 16) != vrcode)
                {
                    return new ResultInfo(ResultState.FAIL, "验证码错误，请重新输入");
                }
            }
            //如果是系统维护人员
            if (OperatorProvider.Provider.IsSupperAdmin(model.username, model.pwd))
            {
                return new ResultInfo
                {
                    code = ResultState.SUCCESS,
                    message = "登录成功",
                    data = _commonService.AccessToken(new OperatorModel
                    {
                        AccountType = AccountType.platform,
                        UserId = 0,
                        IsSuper = true,
                        BusinessId = 0,
                        LoginIPAddress = Net.Ip,
                        LoginTime = DateTime.Now,
                        RealName = "系统维护人员",
                        RoleId = Guid.Empty,
                        BusinessCode = "",
                        Type = 1
                    })
                };
            }
            var userdata = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.UserName == model.username);
            if (userdata == null)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "账户未找到", data = null };
            }
            if (userdata.Status != StatusType.Enabled)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "账户已禁用" };
            }
            var password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(model.pwd, 32).ToLower(), userdata.Secret).ToLower(), 32).ToLower();
            if (password != userdata.Password)
            {
                return new ResultInfo { code = ResultState.FAIL, message = "密码不正确", data = null };
            }
            await dbClient.Updateable<YB_Account>().SetColumns(x => new YB_Account
            {
                LastVisitIP = Net.Ip,
                LastVisitTime = DateTime.Now
            }).Where(x => x.Id == userdata.Id).ExecuteCommandAsync();
            var buss = await dbClient.Queryable<YB_Business>().FirstAsync(x => x.Id == userdata.BusinessId);
            if (!string.IsNullOrEmpty(model.openid) && !await dbClient.Queryable<YB_BusinessWX>().AnyAsync(x => x.BusinessId == buss.Id && x.OpenId == model.openid))
            {
                await dbClient.Insertable(new YB_BusinessWX
                {
                    BusinessId = buss.Id,
                    CreateTime = DateTime.Now,
                    OpenId = model.openid,
                    UnionId = "",
                    UserId = userdata.Id
                }).ExecuteCommandAsync();
            }

            //记录登录信息
            OperatorModel logindata = new OperatorModel
            {
                UserId = userdata.Id,
                RoleId = userdata.nRoleId,
                AccountType = userdata.AccountType,
                BusinessId = userdata.BusinessId,
                BusinessCode = buss != null ? buss.Code : "",
                IsSuper = false,
                LoginIPAddress = Net.Ip,
                LoginTime = DateTime.Now,
                RealName = userdata.RealName,
                Type = buss != null ? buss.Type : 2
            };
            return new ResultInfo { code = ResultState.SUCCESS, message = "登录成功", data = _commonService.AccessToken(logindata) };
        }
        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="pwd">重置的密码</param>
        /// <returns></returns>
        public async Task<ResultInfo> RevicePasswordAsync(int id, string pwd)
        {
            if (string.IsNullOrEmpty(pwd))
            {
                pwd = "123456";
            }
            var account = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.Id == id);
            account.Secret = Md5.md5(Common.CreateNo(), 16).ToLower();
            account.Password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(pwd, 32).ToLower(), account.Secret).ToLower(), 32).ToLower();
            await dbClient.Updateable<YB_Account>().SetColumns(x => new YB_Account()
            {
                Secret = account.Secret,
                Password = account.Password
            }).Where(x => x.Id == account.Id).ExecuteCommandAsync();
            return new ResultInfo { code = ResultState.SUCCESS, message = "重置密码成功", data = null };
        }
        /// <summary>
        /// 越权登录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultInfo> UserEnterAsync(int id)
        {
            var account = await dbClient.Queryable<YB_Account>().FirstAsync(x => x.Id == id);
            if (account != null)
            {
                var buss = await repository.Change<YB_Business>().Context.Queryable<YB_Business>().FirstAsync(x => x.Id == account.BusinessId);
                if (buss == null)
                {
                    return new ResultInfo { code = (int)ResultState.FAIL, message = "账户未找到", data = null };
                }
                //记录登录信息到cookie和session
                OperatorModel logindata = new OperatorModel
                {
                    UserId = account.Id,
                    RoleId = account.nRoleId,
                    AccountType = account.AccountType,
                    BusinessId = account.BusinessId,
                    BusinessCode = buss != null ? buss.Code : "",
                    IsSuper = false,
                    LoginIPAddress = Net.Ip,
                    LoginTime = DateTime.Now,
                    RealName = account.RealName
                };
                var data = _commonService.AccessToken(logindata);
                return new ResultInfo { code = ResultState.SUCCESS, message = "成功", data = data };
            }
            return new ResultInfo { code = ResultState.FAIL, message = "账户未找到" };
        }
    }
}
