using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using NLog;
using System.Net.Http;
using Sugar.Enties;
using Newtonsoft.Json;
using Utils.Jwt;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Authorization;
using Utils;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.IO;
using Newtonsoft.Json.Linq;

namespace PMS.NetCore.Controllers
{
    /// <summary>
    /// 用户信息
    /// </summary>
    [Produces("application/json;charset=UTF-8")]
    [Route("api/User")]
    [ServiceFilter(typeof(Filter.TokenAuthorize))]
    public class UserController : BaseController
    {
        /// <summary>
        /// 加密关键字
        /// </summary>
        private const string EncryptKeyStr = "EcodeIAP"; //加密关键字
        private readonly IHttpClientFactory _httpclientfactory;
        private IMemoryCache _memoryCache;
        private readonly SignInManager<AppUser> _signInManager;
        private readonly UserManager<AppUser> _userManager;
        private readonly IConfiguration _configuration;
        /// <summary>
        /// 令牌获取和验证类
        /// </summary>
        private readonly ITokenHelper tokenHelper = null;
        /// <summary>
        /// 用户信息控制器
        /// </summary>
        /// <param name="memoryCache"></param>
        /// <param name="httpclientfactory"></param>
        /// <param name="userManager"></param>
        /// <param name="signInManager"></param>
        /// <param name="_tokenHelper"></param>
        /// <param name="configuration"></param>
        public UserController(IMemoryCache memoryCache, IHttpClientFactory httpclientfactory, UserManager<AppUser> userManager,
            SignInManager<AppUser> signInManager, ITokenHelper _tokenHelper,
            IConfiguration configuration)
        {
            _httpclientfactory = httpclientfactory;
            _memoryCache = memoryCache;

            _userManager = userManager;
            _signInManager = signInManager;
            _configuration = configuration;
            tokenHelper = _tokenHelper;
            logger = NLog.LogManager.GetCurrentClassLogger();
        }
        /// <summary>
        /// 测试方法
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        [Route("Test")]
        public JsonResult Test()
        {
            return Json("success");
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="request">用户名，密码</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("ValidateUser")]
        public JsonResult ValidateUser([FromBody] UserLoginDTO request)
        {
            // Console.WriteLine("request:" + JsonConvert.SerializeObject(request));
            logger.Info($"【ValidateUser】登录接口输入参数：{JsonConvert.SerializeObject(request)}");

            var user = new usersManager().GetList(m => m.UserID == request.UserId).FirstOrDefault();
            var loginUser = new LoginUserDTO();
            if (user == null)
            {
                var res1 = new ApiResponse
                {
                    Code = 200,
                    IsSuccess = false,
                    ErrMsg = "用户不存在"

                };
                return Json(res1);
            }
            logger.Info($"【ValidateUser】密码：{user.Password}");
            if (ComparePasswords(user.Password, request.Password))
            {
                var isLock = user.IsLock == 0 ? false : true;
                var isSys = user.IsSystem == 1 ? true : false;
                if (!isLock || isSys)
                {
                    //获取用户的所有角色
                    var rolesList = new rolesManager().GetRoles(user.StaffCode);
                    logger.Info($"【ValidateUser】角色：{JsonConvert.SerializeObject(rolesList)}");
                    loginUser.Roles = rolesList;
                    loginUser.User = user;
                    loginUser.User.Password = "";    //密码不返回接口
                }
                else
                {
                    var res1 = new ApiResponse
                    {
                        Code = 200,
                        IsSuccess = false,
                        ErrMsg = "帐号已被冻结"

                    };
                    return Json(res1);
                }

            }
            else
            {

                var res1 = new ApiResponse
                {
                    Code = 200,
                    IsSuccess = false,
                    ErrMsg = "密码错误"

                };
                logger.Info($"【ValidateUser】角色：{JsonConvert.SerializeObject(res1)}");

                return Json(res1);


            }
            //loginUser.License = new licenseManager().GetList().FirstOrDefault();
            //logger.Info($"【ValidateUser】License：{JsonConvert.SerializeObject(loginUser.License)}");
            loginUser.DeptName = new deptsManager().Db.Queryable<depts>().First(m => m.DeptCode == loginUser.User.DeptCode)?.DeptName;

  
            logger.Info($"【ValidateUser】DeptName：{loginUser.DeptName}");

            //获取令牌，返回客户端
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>
                    {
                        { "UserID", user.UserID }
                    };
            var tnToken = tokenHelper.CreateToken(keyValuePairs);

            logger.Info($"【ValidateUser】tnToken：{tnToken}");

            //new Utils.CacheHelper(_memoryCache).SetCache(loginUser.User.UserID, loginUser.User);
            SetCookies("UserID", JsonConvert.SerializeObject(loginUser.User));
            var res = new ApiResponse
            {
                Code = 200,
                IsSuccess = true,
                ErrMsg = "",
                Data = loginUser,
                TnToken = tnToken
            };
            logger.Info($"【ValidateUser】登录接口输出：{JsonConvert.SerializeObject(res)}");
            return Json(res);
        }
        /// <summary>
        /// 根据用户编号获取用户所有角色
        /// </summary>
        /// <param name="staffcode">用户编号</param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetRoles")]
        public JsonResult GetRoles([FromBody] SingleParamDTO staffcode)
        {
            logger.Info($"【GetRoles】staffcode:{JsonConvert.SerializeObject(staffcode)}");
            //获取用户的所有角色
            var rolesList = new rolesManager().GetRoles(staffcode.value);
            logger.Info($"【GetRoles】rolesList:{JsonConvert.SerializeObject(rolesList)}");
            return Json(rolesList);
        }
        /// <summary>
        /// 根据用户编号获取打印权限
        /// </summary>
        /// <param name="staffcode"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetPrintfiles")]
        public JsonResult GetPrintfiles([FromBody] SingleParamDTO staffcode)
        {
            logger.Info($"【GetPrintfiles】staffcode:{JsonConvert.SerializeObject(staffcode)}");
            //获取打印权限
            var printList = new rolesManager().GetPrintfiles(staffcode.value);
            logger.Info($"【GetPrintfiles】printList:{JsonConvert.SerializeObject(printList)}");
            return Json(printList);
        }
        /// <summary>
        /// 根据用户编号获取用户消息语句权限
        /// </summary>
        /// <param name="staffcode"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetMsgtypes")]
        public JsonResult GetMsgtypes([FromBody] SingleParamDTO staffcode)
        {
            logger.Info($"【GetMsgtypes】staffcode:{JsonConvert.SerializeObject(staffcode)}");
            //获取打印权限
            var msgList = new rolesManager().GetMsgtypes(staffcode.value);
            logger.Info($"【GetMsgtypes】msgList:{JsonConvert.SerializeObject(msgList)}");
            return Json(msgList);
        }

        /// <summary>
        /// 根据角色ID获取用户功能模块权限
        /// </summary>
        /// <param name="roleid"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetFuncs")]
        public JsonResult GetFuncs([FromBody] SingleParamDTO roleid)
        {
            logger.Info($"【GetFuncs】roleid:{JsonConvert.SerializeObject(roleid)}");
            //获取打印权限
            var List = new rolesManager().GetFuncs(roleid.value);
            logger.Info($"【GetFuncs】List:{JsonConvert.SerializeObject(List)}");
            return Json(List);
        }

        #region 比较存储在数据库中的用户密码和输入的用户密码是否一致
        /// <summary>
        /// 比较存储在数据库中的用户密码和输入的用户密码是否一致
        /// </summary>
        /// <param name="storedPassword">存储在数据库中的用户密码</param>
        /// <param name="inputPassword">输入的用户密码</param>
        /// <returns>true or false</returns>
        private bool ComparePasswords(String storedPassword, String inputPassword)
        {
            if (storedPassword == String.Empty || inputPassword == String.Empty)
                return false;

            // 得到加密后的密码
            String EncryptedPassword = CreateDbPassword(inputPassword);
            if (storedPassword == EncryptedPassword)
                return true;
            else
                return false;
        }
        private String CreateDbPassword(String unEncryptPassword)
        {
            return Encrypt(unEncryptPassword, EncryptKeyStr);

        }
        #endregion

        #region 加密操作
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="datastr">要加密的字符串</param>
        /// <param name="keystr">机密密钥</param>
        /// <returns>加密后的字符串</returns>
        private String Encrypt(String datastr, String keystr)
        {
            DESCryptoServiceProvider desc = new DESCryptoServiceProvider();//des进行加密

            byte[] key = System.Text.Encoding.ASCII.GetBytes(keystr);
            byte[] data = System.Text.Encoding.Unicode.GetBytes(datastr);

            MemoryStream ms = new MemoryStream();//存储加密后的数据
            CryptoStream cs = new CryptoStream(ms, desc.CreateEncryptor(key, key), CryptoStreamMode.Write);

            cs.Write(data, 0, data.Length);//进行加密
            cs.FlushFinalBlock();

            return System.Convert.ToBase64String(ms.ToArray());//取加密后的数据

        }
        #endregion

        #region 解密操作
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="datastr">要解密的字符串</param>
        /// <param name="keystr">机密密钥</param>
        /// <returns>解密后的字符串</returns>
        private String Decrypt(String datastr, String keystr)
        {
            byte[] data = System.Convert.FromBase64String(datastr);

            DESCryptoServiceProvider desc = new DESCryptoServiceProvider();

            byte[] key = System.Text.Encoding.ASCII.GetBytes(keystr);

            MemoryStream ms = new MemoryStream();//存储解密后的数据
            CryptoStream cs = new CryptoStream(ms, desc.CreateDecryptor(key, key), CryptoStreamMode.Write);

            cs.Write(data, 0, data.Length);//解密数据
            cs.FlushFinalBlock();

            return System.Text.Encoding.Unicode.GetString(ms.ToArray());
        }
        #endregion

    }
}
