using IdentityModel;
using IdentityServer4.Extensions;
using IdentityServer4.Models;
using IdentityServer4.Services;
using Long.Common.Basedata;
using Long.Common.Enums;
using Long.DAO.Basedata;
using System.Security.Claims;

namespace Auth
{
    public class DefaultProfileService : IProfileService
    {
        private readonly ISystemUserDatabase _systemUserDatabase = new SystemUserDatabase();
        private readonly IUserDatabase _userDatabase = new UserDatabase();

        /// <summary>
        /// 只要有关用户的身份信息单元被请求（例如在令牌创建期间或通过用户信息终点），就会调用此方法
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var subject = context.Subject;
            if (subject == null)
            {
                throw new ArgumentNullException(nameof(context.Subject));
            }
            var subjectId = subject.GetSubjectId();

            if (context.Client.ClientId == UserTypeEnum.Admin.ToString().ToLower())
            {
                // 系统用户登录
                var systemUser = await _systemUserDatabase.GetFirstAsync(long.Parse(subjectId));
                if (systemUser == null)
                {
                    throw new ArgumentException("Invalid subject identifier");
                }

                var claims = GetClaimsFromUser(systemUser);

                context.IssuedClaims.AddRange(claims);
            }
            else if (context.Client.ClientId == UserTypeEnum.User.ToString().ToLower())
            {
                // 系统用户登录
                var user = await _userDatabase.GetFirstAsync(long.Parse(subjectId));
                if (user == null)
                {
                    throw new ArgumentException("Invalid subject identifier");
                }

                var claims = GetClaimsFromUser(user);

                context.IssuedClaims.AddRange(claims);
            }
        }

        /// <summary>
        /// 验证用户是否有效 例如：token创建或者验证
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual async Task IsActiveAsync(IsActiveContext context)
        {
            if (context.Client.ClientId == UserTypeEnum.Admin.ToString().ToLower())
            {
                var user = await _systemUserDatabase.GetFirstAsync(long.Parse(context.Subject.GetSubjectId()));
                context.IsActive = user?.Opened == true;
            }
            else if (context.Client.ClientId == UserTypeEnum.User.ToString().ToLower())
            {
                var user = await _userDatabase.GetFirstAsync(long.Parse(context.Subject.GetSubjectId()));
                context.IsActive = user?.Opened == true;
            }
        }

        /// <summary>
        /// 获取声明列表
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private IEnumerable<Claim> GetClaimsFromUser(SystemUser user)
        {
            var claims = new List<Claim>
            {
                new Claim(JwtClaimTypes.Id, user.Id.ToString()),
                new Claim("UserName", user.UserName)
            };

            return claims;
        }

        /// <summary>
        /// 获取声明列表
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private IEnumerable<Claim> GetClaimsFromUser(User user)
        {
            var claims = new List<Claim>
            {
                new Claim(JwtClaimTypes.Id, user.Id.ToString()),
                new Claim("UserName", user.UserName)
            };

            return claims;
        }
    }
}
