using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using ViewModels;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using ViewModels.RequestData;
using ViewModels.ResponseData;
using WebAPIServer.Extensions;
using WebAPIServer.Models;
using System.Net;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using RestSharp;
using UAParser;
using UAParser.Objects;
using NLog;

namespace WebAPIServer.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class LoginController : ControllerBase
    {


        public IConfiguration? configuration { get; set; }
        public LoginController(IConfiguration _configuration)
        {
            configuration = _configuration;
        }
        [Authorize()]
        [HttpPost()]
        public ReturnInfo TokenXuQi()
        {
            ReturnInfo r = new ReturnInfo();
            r.isok = false;
            try
            {
                var claims = HttpContext.AuthenticateAsync().Result?.Principal?.Claims;
                if (claims != null && claims.Any())
                {
                    var Name = claims.SingleOrDefault(A => A.Type == ClaimTypes.Name)?.Value;
                    var UUU = claims.SingleOrDefault(A => A.Type == ClaimTypes.Role)?.Value;
                    var TTT = claims.SingleOrDefault(A => A.Type == ClaimTypes.NameIdentifier)?.Value;

                    TblUtsManageUser? HH = new TblUtsManageUser();
                    int a = 0;
                    int.TryParse(TTT, out a);
                    HH.Id = a;
                    bool bl = false;
                    bool.TryParse(UUU, out bl);
                    HH.IsAdmin = bl;
                    HH.UserName = Name;
                    string TokenStr = GetToken(HH);
                    r.isok = true;
                    r.response = TokenStr;
                }
            }
            catch (Exception ex)
            {
                r.isok = false;
                r.message = ex.Message;
            }
            return r;

            //var identity = HttpContext.User.Identity as ClaimsIdentity;
            //if (identity != null)
            //{
            //    var userClaims = identity.Claims;
            //}
            //return "hello world";
        }


        [HttpGet()] // 例如，一个获取验证码的API端点
        public IActionResult GetCaptcha()
        {
            string captchaText; // 这里使用上面任一版本的GenerateCaptchaImage方法生成的文本。例如：captchaText = CaptchaHelperSkiaSharp.GenerateCaptchaImage(out captchaText); 或 captchaText = CaptchaHelper.GenerateCaptchaImage(out captchaText); 根据你的选择。 
            byte[] imageBytes = CaptchaHelperSkiaSharp.GenerateCaptchaImage(); // 或者使用System.Drawing的方法。确保你选择了
            return Ok(new { CaptchaText = "1111", Image = Convert.ToBase64String(imageBytes) });
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        [HttpPost]
        public ReturnInfo Login([FromBody] LoginData data)
        {

            ReturnInfo res = new ReturnInfo();

            try
            {
                string password = data.password;
                string username = data.username;
                TblUtsManageUser? entity = null;
                string TokenString = "";
                string pwd = password.ToMD5().ToMD5();
                using (var q = new UtsManageContext())
                {
                    entity = q.TblUtsManageUsers.SingleOrDefault(A => A.UserName.Equals(username) && A.Password.Equals(pwd));
                    if (entity != null)
                    {
                        var auths = q.TblUtsManageUserauthOperations.Where(A => A.UserId == entity.Id).ToList();
                        TokenString = GetToken(entity);
                        res.isok = true;



                        ResLoginData r = new ResLoginData();
                        r.AccessToken = TokenString;
                        r.IsAdmin = entity.IsAdmin;
                        r.ID = entity.Id;
                        r.UserName = entity.UserName;
                        r.Auths = auths;
                        res.response = r;
                    }
                    else
                    {
                        res.isok = false;
                        res.message = "用户名或密码错误";
                    }
                }
            }
            catch (Exception ex)
            {
                res.message = ex.Message;
                res.isok = false;
            }
            return res;
        }

        private string GetToken(TblUtsManageUser? entity)
        {
            string TokenString;
            var claims = new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, entity.Id.ToString()),
                new Claim(ClaimTypes.Role, entity.IsAdmin.ToString()),
                new Claim(ClaimTypes.Name, entity.UserName)
            };

            var secretByte = Encoding.UTF8.GetBytes(configuration["JwT:SecretKey"]);
            var signingKey = new SymmetricSecurityKey(secretByte);
            var a = SecurityAlgorithms.HmacSha256;

            var signingCredentials = new SigningCredentials(signingKey, a);

            var token = new JwtSecurityToken(
                issuer: configuration["JwT:Issuer"],
                audience: configuration["JwT:Audience"],//接收
                claims: claims,//存放的用户信息
                notBefore: DateTime.UtcNow,//发布时间
                expires: DateTime.UtcNow.AddDays(3),//过期时间
                signingCredentials: signingCredentials
           //有效期设置为1天signingCredentials //数字名
           );
            TokenString = new JwtSecurityTokenHandler().WriteToken(token);
            return TokenString;
        }

        public class LLLG
        {
            public string UserName { get; set; }
            public string Database { get; set; }
        }
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        [Authorize()]
        [HttpPost()]
        public ReturnInfo LogRecord([FromBody] LLLG data)
        {

            ReturnInfo res = new ReturnInfo();


            try
            {

                string Device = "Unknown";
                #region  记录登录信息
                var userAgent = Request.Headers["User-Agent"].ToString();
                bool
                    _windows = userAgent.Contains("Windows NT"),
                    _mac = userAgent.Contains("Macintosh"),
                    _iphone = userAgent.Contains("iPhone"),
                    _android = userAgent.Contains("Android")
                    ;
                if (_windows)
                {
                    Device = "windows";
                }
                else if (_mac)
                {
                    Device = "Mac";
                }
                else if (_iphone)
                {
                    Device = "ios";
                }
                else if (_android)
                {
                    Device = "Android";
                }
                else
                {
                    Device = "未知";
                }
                #endregion

                //获得IP
                string? ip = string.Empty;
                string? NNN = HttpContext?.Request?.HttpContext?.Connection?.RemoteIpAddress?.ToString();
                if (string.IsNullOrEmpty(NNN))
                {
                    ip = HttpContext?.Request.Headers["HTTP_X_FORWARDED_FOR"];
                }
                else
                {
                    ip = NNN;
                }

                var uaParser = Parser.GetDefault();

                ClientInfo c = uaParser.Parse(userAgent);

                using (var q = new UtsManageContext())
                {
                    TblUtsUseroperation t = new TblUtsUseroperation();
                    t.CreationTime = DateTime.Now;
                    t.UserName = data.UserName;
                    t.Ip = ip;
                    t.Browser = c.Browser.Family + " " + c.Browser.Major + "." + c.Browser.Minor;
                    t.Operation = "登录";
                    t.Database = data.Database;
                    t.Device = Device;

                    if (ip.Equals("::1"))
                    {
                        t.Location = "本地";
                    }
                    else
                    {
                        t.Location = GetBaiduIp(ip);
                    }
                    q.TblUtsUseroperations.Add(t);
                    q.SaveChanges();

                    res.isok = true;
                    res.response = "sucess";
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                res.isok = false;
                res.response = ex.Message;
            }

            return res;
        }

        public static void UserLog(string Openration, string Device)
        {


        }

        [HttpPost()]
        [Authorize()]
        public string Helloooo()
        {
            return "hello";
        }

        [HttpGet()]
        public string AccessDenied()
        {
            return "aaaa";
        }


        /// <summary>
        /// 百度api
        /// </summary>
        /// <returns></returns>
        public static string GetBaiduIp(string ip)
        {
            string location = "";
            try
            {
                string url = $"https://sp0.baidu.com";
                //WebClient client = new WebClient();
                RestSharp.RestClient client1 = new RestSharp.RestClient(url);
                RestSharp.RestRequest request = new RestSharp.RestRequest($"/8aQDcjqpAAV3otqbppnN2DJv/api.php?query={ip}&co=&resource_id=6006&oe=utf8", Method.Get);
                var buffer = client1.DownloadData(request);
                //var buffer = client.DownloadData(url);
                string jsonText = Encoding.UTF8.GetString(buffer);
                JObject jo = JObject.Parse(jsonText);

                Root root = JsonConvert.DeserializeObject<Root>(jo.ToString());
                foreach (var item in root.data)
                {
                    location = item.location;
                }
                return location;
            }
            catch (Exception ex)
            {
                //Console.WriteLine(ex);
                return location;
            }

        }

    }

    public class Root
    {
        public List<DataItem> data { get; set; }
    }
    public class DataItem
    {
        /// <summary>
        /// 
        /// </summary>
        public string ExtendedLocation { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string OriginQuery { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string appinfo { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int disp_type { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string fetchkey { get; set; }
        /// <summary>
        /// 本地局域网
        /// </summary>
        public string location { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string origip { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string origipquery { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string resourceid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int role_id { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int shareImage { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int showLikeShare { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string showlamp { get; set; }
        /// <summary>
        /// IP地址查询
        /// </summary>
        public string titlecont { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string tplt { get; set; }
    }
}
