using System.Threading;
using System.Threading.Tasks;
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Linq;
using Abp.Organizations;
using YGNT.Exam.Authorization.Roles;

namespace YGNT.Exam.Authorization.Users
{
    public class UserStore : AbpUserStore<Role, User>
    {
        public UserStore(
            IUnitOfWorkManager unitOfWorkManager,
            IRepository<User, long> userRepository,
            IRepository<Role> roleRepository,
            IAsyncQueryableExecuter asyncQueryableExecuter,
            IRepository<UserRole, long> userRoleRepository,
            IRepository<UserLogin, long> userLoginRepository,
            IRepository<UserClaim, long> userClaimRepository,
            IRepository<UserPermissionSetting, long> userPermissionSettingRepository,
            IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
            IRepository<OrganizationUnitRole, long> organizationUnitRoleRepository)
            : base(
                unitOfWorkManager,
                userRepository,
                roleRepository,
                asyncQueryableExecuter,
                userRoleRepository,
                userLoginRepository,
                userClaimRepository,
                userPermissionSettingRepository,
                userOrganizationUnitRepository,
                organizationUnitRoleRepository)
        {
        }


        /// <summary>
        /// 使用手机号代替邮箱
        /// </summary>
        /// <param name="userNameOrEmailAddress"></param>
        /// <returns></returns>
        public override async Task<User> FindByNameOrEmailAsync(string userNameOrEmailAddress)
        {
            var normalizedUserNameOrEmailAddress = NormalizeKey(userNameOrEmailAddress);

            return await UserRepository.FirstOrDefaultAsync(
                user => user.NormalizedUserName == normalizedUserNameOrEmailAddress
                        || user.PhoneNumber == normalizedUserNameOrEmailAddress
            );
        }


        /// <summary>
        /// 使用手机号代替邮箱
        /// </summary>
        /// <param name="userNameOrEmailAddress"></param>
        /// <returns></returns>
        public override User FindByNameOrEmail(string userNameOrEmailAddress)
        {
            string normalizedUserNameOrEmailAddress = NormalizeKey(userNameOrEmailAddress);

            return UserRepository.FirstOrDefault(user =>
                user.NormalizedUserName == normalizedUserNameOrEmailAddress
                || user.PhoneNumber == normalizedUserNameOrEmailAddress);
        }

        public virtual Task<User> FindByPhoneNumberAsync(string phoneNumber, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            return UserRepository.FirstOrDefaultAsync(u => u.PhoneNumber == phoneNumber);
        }
    }
}
