using IRaCIS.Core.Domain.Models;
using Microsoft.AspNetCore.Http;
using UAParser;

namespace IRaCIS.Core.Domain.Share
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public class UserInfo(IHttpContextAccessor _accessor, Parser parser) : IUserInfo
    {


        /// <summary>
        /// 用户角色Id  
        /// </summary>
        public Guid UserRoleId
        {
            get
            {
                var id = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserRoleId);
                if (id != null && !string.IsNullOrEmpty(id.Value))
                {
                    return Guid.Parse(id.Value);
                }
                return Guid.Empty;
            }
        }

        /// <summary>
        /// 真实用户Id
        /// </summary>
        public Guid IdentityUserId
        {
            get
            {
                var id = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.IdentityUserId);
                if (id != null && !string.IsNullOrEmpty(id.Value))
                {
                    return Guid.Parse(id.Value);
                }
                return Guid.Empty;
            }
        }

        public Guid UserTypeId
        {
            get
            {
                var userTypeId = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeId);
                if (userTypeId != null && !string.IsNullOrEmpty(userTypeId.Value))
                {
                    return Guid.Parse(userTypeId.Value);
                }
                return Guid.Empty;
            }
        }


        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get
            {
                var name = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserName);

                if (name != null && !string.IsNullOrEmpty(name.Value))
                {
                    return name.Value;
                }

                return "";
            }
        }


        public string FullName
        {
            get
            {
                var name = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName);

                if (name != null && !string.IsNullOrEmpty(name.Value))
                {
                    return name.Value;
                }

                return "";
            }
        }




        public string UserTypeShortName
        {
            get
            {
                var userType = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName);

                if (userType != null && !string.IsNullOrEmpty(userType.Value))
                {
                    return userType.Value;
                }
                return string.Empty;
            }
        }



        public string UserTypeEnumStr
        {
            get
            {
                var userType = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeEnum);

                if (userType != null && !string.IsNullOrEmpty(userType.Value))
                {
                    return userType.Value;
                }
                return UserTypeEnum.ShareImage.ToString();
            }
        }

        public int UserTypeEnumInt
        {
            get
            {
                var userType = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeEnumInt);

                if (userType != null && !string.IsNullOrEmpty(userType.Value))
                {
                    return int.Parse(userType.Value);
                }
                return 0;
            }
        }

        public bool IsAdmin
        {
            get
            {
                var userType = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeEnumInt);

                if (userType != null && !string.IsNullOrEmpty(userType.Value))
                {
                    return int.Parse(userType.Value) == (int)UserTypeEnum.SuperAdmin;
                }
                return false;
            }
        }

        public bool IsZhiZhun
        {
            get
            {
                var isZhizhunClaime = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.IsZhiZhun);

                if (isZhizhunClaime != null && !string.IsNullOrEmpty(isZhizhunClaime.Value))
                {
                    return bool.Parse(isZhizhunClaime.Value);
                }
                return false;
            }
        }

        public bool IsTestUser
        {
            get
            {
                var isTestUserClaime = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.IsTestUser);

                if (isTestUserClaime != null && !string.IsNullOrEmpty(isTestUserClaime.Value))
                {
                    return bool.Parse(isTestUserClaime.Value);
                }
                return false;
            }
        }

        public string UserToken
        {
            get
            {

                var authorizationHeader = _accessor?.HttpContext?.Request.Headers["Authorization"].ToString();
                if (!string.IsNullOrWhiteSpace(authorizationHeader))
                {
                    return authorizationHeader.Substring(7);

                }

                var token = _accessor?.HttpContext?.Request.Query["access_token"].ToString();

                if (!string.IsNullOrWhiteSpace(token))
                {
                    return token;

                }
                return string.Empty;


            }
        }

        public string PermissionStr
        {
            get
            {
                var permissionStr = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.PermissionStr);

                if (permissionStr != null && !string.IsNullOrEmpty(permissionStr.Value))
                {
                    return permissionStr.Value;
                }
                return string.Empty;
            }
        }

        public string IP
        {
            get
            {

                return _accessor?.HttpContext?.GetClientIP() ?? string.Empty;
            }
        }


        public string Domain
        {
            get
            {

                return _accessor?.HttpContext?.Request.Host.Host ?? string.Empty;
            }
        }


        public string LocalIp
        {
            get
            {

                return _accessor?.HttpContext?.Connection?.LocalIpAddress?.MapToIPv4().ToString() ?? string.Empty;
            }
        }


        public bool IsEn_Us
        {
            get
            {
                var lan = _accessor?.HttpContext?.Request?.Headers["Accept-Language"];

                if (lan is not null && !string.IsNullOrEmpty(lan.Value))
                {
                    return lan.Value == "en-US,en;q=0.5".ToString();
                }
                return true;
            }
        }


        public string RequestUrl
        {

            get
            {
                var url = _accessor?.HttpContext?.Request?.Path.ToString();

                var list = url.Split('/').Where(t => !string.IsNullOrWhiteSpace(t)).ToList();

                if (url.Contains("Inspection", StringComparison.OrdinalIgnoreCase))
                {
                    list.RemoveAt(0);

                    return string.Join('/', list.Take(2));
                }
                else
                {
                    return string.Join('/', list.Take(2));
                }


            }
        }

        public string TimeZoneId
        {

            get
            {
                var timeZoneId = _accessor?.HttpContext?.Request?.Headers["TimeZoneId"];

                if (timeZoneId is not null && !string.IsNullOrEmpty(timeZoneId.Value))
                {
                    return timeZoneId.Value;
                }

                //return "Etc/UTC";
                return "Asia/Shanghai";


            }
        }

        public string BrowserFingerprint
        {
            get
            {
                var browserFingerprint = _accessor?.HttpContext?.Request?.Headers["BrowserFingerprint"];

                if (browserFingerprint is not null && !string.IsNullOrEmpty(browserFingerprint.Value))
                {
                    return browserFingerprint.Value;
                }

                //return "Etc/UTC";
                return Guid.NewGuid().ToString();


            }
        }

        public UserWorkLanguage UserWorkLanguage
        {
            get
            {
                var userWorkLanguage = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.UserWorkLanguage);

                if (userWorkLanguage != null && !string.IsNullOrEmpty(userWorkLanguage.Value))
                {
                    return Enum.Parse<UserWorkLanguage>(userWorkLanguage.Value);
                }
                else
                {
                    return UserWorkLanguage.US;

                }
            }

        }

        public ClientInfo ClientInfo
        {
            get
            {
                try
                {
                    var userAgent = _accessor?.HttpContext.Request.Headers["User-Agent"].ToString();

                    if (!string.IsNullOrEmpty(userAgent))
                    {
                        var clientInfo = parser.Parse(userAgent);

                        return new ClientInfo()
                        {
                            OS = clientInfo.OS.ToString(),
                            Browser = clientInfo.UA.ToString(),
                            DeviceType = userAgent.Contains("Mobile") ? "Mobile" : "Desktop"
                        };



                    }
                    else
                    {

                        return new ClientInfo()
                        {
                            OS = "Unknown",
                            Browser = "Unknown",
                            DeviceType = "Unknown"
                        };


                    }
                }
                catch (Exception ex)
                {

                    return new ClientInfo()
                    {
                        OS = "ParseError",
                        Browser = "ParseError",
                        DeviceType = "ParseError"
                    };

                }
            }
        }


        public Guid? SignId
        {

            get; set;
        }


        public Guid? BatchId
        {

            get; set;
        }


        /// <summary>
        /// 是否不需要记录稽查
        /// </summary>
        public bool IsNotNeedInspection { get; set; } = false;

        /// <summary>
        /// 稽查额外字符串
        /// </summary>
        public string AuditIdentification { get; set; } = string.Empty;
    }

    public static class ClaimAttributes
    {
        /// <summary>
        /// 用户Id
        /// </summary>
        public const string UserId = "id";

        public const string UserTypeId = "userTypeId";

        /// <summary>
        /// 用户名
        /// </summary>
        public const string UserName = "name";

        /// <summary>
        /// 姓名
        /// </summary>
        public const string RealName = "realName";

        public const string ReviewerCode = "reviewerCode";

        public const string UserType = "userTypeShortName";
    }

    public struct JwtIRaCISClaimType
    {
        public const string IdentityUserId = "identityUserId";
        public const string UserRoleId = "userRoleId";
        public const string Code = "code";
        public const string UserName = "name";
        public const string FullName = "fullName";
        public const string UserTypeId = "userTypeId";
        public const string UserTypeEnum = "userTypeEnum";
        public const string UserTypeEnumName = "userTypeEnumName";
        public const string UserTypeEnumInt = "userTypeEnumInt";
        public const string UserTypeShortName = "userTypeShortName";

        public const string IsTestUser = "isTestUser";

        public const string IsZhiZhun = "isZhiZhun";

        public const string PermissionStr = "permissionStr";

        public const string UserWorkLanguage = "userWorkLanguage";

    }

    public static class HttpContextExtension
    {
        public static string GetClientIP(this HttpContext context)
        {
            //scp 服务创建的记录不能获取请求上下文
            if (context != null)
            {
                var ip = context.Request.Headers["Cdn-Src-Ip"].FirstOrDefault();
                if (!string.IsNullOrEmpty(ip))
                    return IpReplace(ip);

                ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
                if (!string.IsNullOrEmpty(ip))
                    return IpReplace(ip);

                ip = context.Connection.RemoteIpAddress.ToString();

                return IpReplace(ip);
            }
            else
            {
                return string.Empty;
            }
        }

        static string IpReplace(string inip)
        {
            //::ffff:
            //::ffff:192.168.2.131 这种IP处理
            if (inip.Contains("::ffff:"))
            {
                inip = inip.Replace("::ffff:", "");
            }
            return inip;
        }
    }
}
