using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using NLog;
using Org.BouncyCastle.Bcpg;
using System;
using WebAPIBase.API.Requests;
using WebAPIBase.Service.Interface;
using Newtonsoft.Json;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net;
using Sugar.Enties;
using System.Text;
using WebAPIBase.Utils;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Claims;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;

namespace WebAPIBase.API.Controllers
{
    [Produces("application/json;charset=UTF-8")]
    [Route("api/User")]
    public class UserController : Controller
    {
        private string webserviceUrl;
        private static Logger Logger = NLog.LogManager.GetCurrentClassLogger();
        private readonly IHttpClientFactory _httpclientfactory;
        private IMemoryCache _memoryCache;
        private readonly SignInManager<AppUser> _signInManager;
        private readonly UserManager<AppUser> _userManager;
        private readonly IConfiguration _configuration;

        public UserController(IMemoryCache memoryCache, IHttpClientFactory httpclientfactory, UserManager<AppUser> userManager,
            SignInManager<AppUser> signInManager,
            IConfiguration configuration)
        {
            _httpclientfactory = httpclientfactory;
            _memoryCache = memoryCache;
            IConfigurationBuilder builder = new ConfigurationBuilder()
              .SetBasePath(Directory.GetCurrentDirectory())
              .AddJsonFile("appsettings.json");

            IConfigurationRoot Configuration = builder.Build();

            webserviceUrl = Configuration["Logging:AppSettings:webserviceUrl"];

            _userManager = userManager;
            _signInManager = signInManager;
            _configuration = configuration;
        }

        [AllowAnonymous]
        [HttpPost]
        [Route("")]
        public ActionResult ValidateUser([FromBody] UserLogin request)
        {
            Console.WriteLine("request:" + JsonConvert.SerializeObject(request));
            NameValueCollection values = new NameValueCollection();
            values.Add("userid", request.UserName);
            values.Add("password", request.Password);
            values.Add("dno", "");
            values.Add("dtoken", "");
            var result = WebClientHelper.ClientPost(webserviceUrl + "/Login", values);

            //Console.WriteLine(result);

            var login = JsonConvert.DeserializeObject<InterfaceLoginReturn>(result);
            Console.WriteLine($"login:{JsonConvert.SerializeObject(login)}");

            var user = new SystemUserManager().GetList(m => m.UserID == "admin").FirstOrDefault();
            var loginUser = new LoginUserDTO();
            loginUser.IsSuccess = login.result;
            //loginUser.IsSuccess = false;
            if (login != null && login.result)
            {
                var unitManager = new UnitManager();
                var userCode = login.data.userCode;
                var station = unitManager.GetUserStation(userCode);
                loginUser.ErrorMsg = "";
                loginUser.roles = new string[1] { "admin" };
                loginUser.introduction = login.data.userName;
                loginUser.name = login.data.userName;
                loginUser.token = login.data.userId;
                loginUser.stationCode = station.StationCode;
                loginUser.stationName = station.StationName;
                loginUser.departmentCode = unitManager.GetUserDepartmentCode(userCode);
                loginUser.departmentName = unitManager.GetUserDepartment(userCode);
                loginUser.avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif";
                user = new SystemUser();
                user.UserCode = login.data.userCode;
                user.UserID = login.data.userId;
                user.UserName = login.data.userName;
                loginUser.User = user;
            }
            else
            {
                //loginUser.ErrorMsg = login.msg;
                //return Json(loginUser);


                var unitManager = new UnitManager();
                var userCode = user.UserCode;
                var station = unitManager.GetUserStation(userCode);
                loginUser.ErrorMsg = "";
                loginUser.roles = new string[1] { "admin" };
                loginUser.introduction = user.UserName;
                loginUser.name = user.UserName;
                loginUser.token = user.UserID;
                loginUser.stationCode = station.StationCode;
                loginUser.stationName = station.StationName;
                loginUser.departmentCode = unitManager.GetUserDepartmentCode(userCode);
                loginUser.departmentName = unitManager.GetUserDepartment(userCode);
                loginUser.avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif";

                loginUser.User = user;
            }
            #region 写入系统日志
            var log = new SysBusinessLog();
            log.LogClass = "SystemUser";
            log.LogTime = DateTime.Now;
            log.ApplicationId2 = loginUser.User.UserCode;
            log.LogType = "登录";
            log.OperatePersonId = Convert.ToInt32(loginUser.User.UserCode);
            log.LogRemark = "";
            log.OperatePerson = loginUser.name;
            new SysBusinessLogManager().Insert(log);     //插入系统日志
            #endregion

            //获取令牌，返回客户端
            AppUser appUser = new AppUser();
            appUser.UserName = user.UserName;
            appUser.Id = user.UserID;
            appUser.SystemUser = user;
            var token = GenerateJwtToken(appUser);
            loginUser.token = token;
            new Utils.CacheHelper(_memoryCache).SetCache(loginUser.User.UserID, loginUser.User);
            return Json(loginUser);
        }

        [AllowAnonymous]
        [HttpGet]
        [Route("getuserinfo")]
        public ActionResult GetUserInfo(string token)
        {
            Console.WriteLine("getuserinfo");
            Console.WriteLine("token:" + token);
            var ret = new Utils.CacheHelper(_memoryCache).GetCache(token);
            //Console.WriteLine("cache:" + JsonConvert.SerializeObject(ret));
            var loginUser = new LoginUserDTO();
            if (ret == null)
            {
                loginUser.IsSuccess = false;
                loginUser.ErrorMsg = "登录超时，请重新登录";

            }
            else
            {
                var user = (SystemUser)ret;
                loginUser.User = user;
                loginUser.IsSuccess = true;
                loginUser.ErrorMsg = "";
                loginUser.token = user.UserID;
                loginUser.name = user.UserName;
                loginUser.avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif";
                loginUser.introduction = "";
                loginUser.roles = new string[1] { "admin" };
            }
            //Logger.Info(ret);
            return Json(loginUser);
        }

        [HttpGet]
        [Route("logout")]
        public ActionResult LogOut(string userid)
        {
            new Utils.CacheHelper(_memoryCache).DelCache(userid);
            return Json(new { code = 20000, data = "success" });
        }

        [AllowAnonymous]
        [HttpPost]
        [Route("create")]
        public JsonResult InsertUser(string username, string password, string confirmpassword)
        {
            if (password == confirmpassword)
            {
                //_userService.InsertUser(username, password);
            }
            return Json("User Created Successfully! :)");
        }

        private async Task<string> remoteHelper(string url, HttpContent content)
        {
            var result = string.Empty;
            try
            {
                using (var client = _httpclientfactory.CreateClient())
                using (var response = await client.PostAsync(url, content))
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        result = await response.Content.ReadAsStringAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            return result;
        }

        private string GenerateJwtToken(AppUser user)
        {
            var claimsIdentity = new ClaimsIdentity(new[]
            {
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.Role, "Admin"),
                new Claim(ClaimTypes.UserData,JsonConvert.SerializeObject(user.SystemUser))
            }); ;

            var tokenHandler = new JwtSecurityTokenHandler();
            DateTime expiry = DateTime.UtcNow.AddMinutes(5);

            JwtSecurityToken token = tokenHandler.CreateJwtSecurityToken(new SecurityTokenDescriptor
            {
                Issuer = _configuration["JWT:Issuer"],
                Audience = _configuration["JWT:Audience"],
                Subject = claimsIdentity,
                IssuedAt = DateTime.UtcNow,
                Expires = expiry,
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(
                        Encoding.Default.GetBytes(_configuration["JWT:Key"])),
                        SecurityAlgorithms.HmacSha256Signature)
            });

            return tokenHandler.WriteToken(token);
        }
    }
}
