using System;
using System.Linq;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Http;

namespace IRaCIS.Core.Domain.Share
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public class UserInfo : IUserInfo
    {
        private readonly IHttpContextAccessor _accessor;

        public UserInfo(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        /// <summary>
        /// 用户Id
        /// </summary>
        public Guid Id
        {
            get
            {
                var id = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.Id);
                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.Name);

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

                return "";
            }
        }


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

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

                return "";
            }
        }

        public string ReviewerCode
        {
            get
            {
                var reviewerCode = _accessor?.HttpContext?.User?.FindFirst(JwtIRaCISClaimType.Code);

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


        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 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?.Connection.RemoteIpAddress.ToString();
            }
        }


        public string LocalIp
        {
            get
            {

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


        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 "Asia/Shanghai";


            }
        }


        public Guid? SignId
        {

            get; set;
        }


        public Guid? BatchId
        {

            get; set;
        }
    }

    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 Id = "id";
        public const string Code = "code";
        public const string Name = "name";
        public const string RealName = "realName";
        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 IsAdmin = "isAdmin";

        public const string IsTestUser = "isTestUser";

        public const string PermissionStr = "permissionStr";


    }
}
