package service

import (
	"time"

	"github.com/GeeTeam/gt3-golang-sdk/geetest"
	"github.com/google/uuid"
	"github.com/linmadan/egglib-go/utils/json"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/auth/dto"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/auth/query"

	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/log"

	"github.com/linmadan/egglib-go/core/application"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/auth/command"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/cache"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/allied_creation_user"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/infrastructure/service_gateway/sms_serve"
)

const (
	captchaID  = "33a2abf9c5df0d6bc3b89fb39280114b"
	privateKey = "13320fd2b10199e9a2440a4fbb4d46f7"
)

// 组织管理
type AuthService struct {
}

//AuthLogin 用户登录
func (svr AuthService) AuthLogin(loginCommand *command.LoginCommand) (interface{}, error) {
	var (
		authCode      string
		result        interface{}
		err           error
		loginPlatform string = domain.LoginPlatformApp
	)
	if loginCommand.DeviceType == domain.DeviceTypeWeb {
		loginPlatform = domain.LoginPlatformWeb
	}
	if len(loginCommand.LoginPlatform) != 0 {
		loginPlatform = loginCommand.LoginPlatform
	}
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	_, err = creationUserGateway.AuthRefreshIM(allied_creation_user.ReqAuthRefreshIM{
		Phone: loginCommand.Phone,
	})
	if err != nil {
		log.Logger.Error("refresh im error:" + err.Error()) // 只做提示继续进行登录
		//return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	switch loginCommand.GrantType {
	case domain.LoginPwd:
		authCode, err = svr.SignInPassword(loginCommand.Phone, loginCommand.Password, loginPlatform)
	case domain.LoginSmsCode:
		authCode, err = svr.SignInCaptcha(loginCommand.Phone, loginCommand.Captcha, loginPlatform)
	default:
		err = application.ThrowError(application.TRANSACTION_ERROR, "登录方式无法解析")
	}
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	result, err = svr.GetAuthAccessToken(&command.AccessTokenCommand{
		AuthCode:      authCode,
		SessionMode:   loginCommand.SessionMode,
		LoginPlatform: loginPlatform,
	})
	return map[string]interface{}{
		"access": result,
	}, err
}

//AuthLogin 用户登录
func (svr AuthService) AuthLoginPwd(loginCommand *command.LoginPwdCommand) (interface{}, error) {
	if err := loginCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	login := &command.LoginCommand{
		GrantType:   "signInPassword",
		Phone:       loginCommand.Username,
		Password:    loginCommand.Password,
		SessionMode: loginCommand.SessionMode,
		DeviceType:  loginCommand.DeviceType,
	}
	if len(loginCommand.CaptchaChallenge) > 0 {
		geetest := geetest.NewGeetestLib(captchaID, privateKey, 2*time.Second)
		validateResult := geetest.SuccessValidate(loginCommand.CaptchaChallenge, loginCommand.CaptchaValidate, loginCommand.CaptchaSeccode, "", "")
		if !validateResult {
			log.Logger.Error("validate captcha fail")
		}
	}
	return svr.AuthLogin(login)
}

//AuthLogin 用户登录
func (svr AuthService) AuthLoginSms(loginCommand *command.LoginSmsCommand) (interface{}, error) {
	if err := loginCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	login := &command.LoginCommand{
		GrantType:   "signInCaptcha",
		Phone:       loginCommand.Phone,
		Captcha:     loginCommand.Code,
		SessionMode: loginCommand.SessionMode,
		DeviceType:  loginCommand.DeviceType,
	}
	return svr.AuthLogin(login)
}

//AuthLoginQrcode 扫码登录
func (svr AuthService) AuthLoginQrcode(queryParam *query.QrcodeLoginStatusQuery) (interface{}, error) {
	failLoginData := map[string]interface{}{
		"isLogin": false,
		"access":  struct{}{},
	}
	cache := cache.LoginQrcodeCache{}
	qrcodeMessage, err := cache.Get(queryParam.Key)
	if err != nil {
		log.Logger.Error(err.Error())
		return nil, application.ThrowError(application.BUSINESS_ERROR, "二维码已失效")
	}
	if !qrcodeMessage.IsLogin {
		return failLoginData, nil
	}

	loginToken := domain.LoginToken{
		UserId:     qrcodeMessage.UserId,
		UserBaseId: qrcodeMessage.UserBaseId,
		Account:    qrcodeMessage.Account,
		Platform:   domain.LoginPlatformWeb,
		CompanyId:  qrcodeMessage.CompanyId,
		OrgId:      qrcodeMessage.OrgId,
	}
	cache.Remove(queryParam.Key)
	result, err := svr.getToken(loginToken)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}

	data := map[string]interface{}{
		"isLogin": qrcodeMessage.IsLogin,
		"access":  result["token"],
	}
	return data, nil
}

//AuthLoginQrcodeBind 扫码登录-绑定
func (svr AuthService) AuthLoginQrcodeBinding(bindingCmd *command.QrcodeBindingCommand) (interface{}, error) {
	qrCache := cache.LoginQrcodeCache{}
	qrcodeMessage, err := qrCache.Get(bindingCmd.Key)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "您扫描的二维码无效,请确认后重新扫描")
	}
	if err := qrcodeMessage.BindUser(bindingCmd.Operator); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	if err := qrCache.Save(*qrcodeMessage); err != nil {
		log.Logger.Error(err.Error())
		return nil, application.ThrowError(application.BUSINESS_ERROR, "登录失败,请重试")
	}
	return struct{}{}, nil
}

//SendSmsCaptcha 发送验证码短信
func (svr AuthService) SendSmsCaptcha(smsCodeCommand *command.SendSmsCodeCommand) error {
	if err := smsCodeCommand.ValidateCommand(); err != nil {
		return application.ThrowError(application.ARG_ERROR, err.Error())
	}
	if smsCodeCommand.Flag == 1 {
		creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
		userBase, err := creationUserGateway.AuthUserBaseInfo(allied_creation_user.ReqAuthUserBase{
			Account: smsCodeCommand.Phone,
		})
		if err != nil || userBase.UserInfo.Phone != smsCodeCommand.Phone {
			return application.ThrowError(application.BUSINESS_ERROR, "输入的手机号不是平台用户,请重新输入")
		}
	}
	smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
	err := smsServeGateway.SendSms(smsCodeCommand.Phone)
	if err != nil {
		return application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return nil
}

//SignInPassword 使用账号密码校验
func (svr AuthService) SignInPassword(account string, password string, loginPlatform string) (string, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	_, err := creationUserGateway.AuthCheckPassword(allied_creation_user.ReqAuthCheckPassword{
		Password: password,
		Phone:    account,
	})
	if err != nil {
		return "", application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	loginToken := domain.LoginToken{
		UserId:    0,
		Account:   account,
		Platform:  loginPlatform,
		CompanyId: 0,
	}
	authCode, err := loginToken.GenerateAuthCode()
	if err != nil {
		return "", application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return authCode, nil
}

//SignInCaptcha 使用手机验证码登录
func (svr AuthService) SignInCaptcha(phone string, captcha string, loginPlatform string) (string, error) {
	smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
	err := smsServeGateway.CheckSmsCode(phone, captcha)
	if err != nil {
		return "", application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	loginToken := domain.LoginToken{
		UserId:    0,
		Account:   phone,
		Platform:  loginPlatform,
		CompanyId: 0,
	}
	authCode, err := loginToken.GenerateAuthCode()
	if err != nil {
		return "", application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return authCode, nil
}

//GetAuthAccessToken 获取令牌Token
func (svr AuthService) GetAuthAccessToken(accessTokenCommand *command.AccessTokenCommand) (interface{}, error) {
	if err := accessTokenCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	loginToken := &domain.LoginToken{}
	err := loginToken.ParseToken(accessTokenCommand.AuthCode)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	loginToken.Platform = accessTokenCommand.LoginPlatform
	loginToken.SessionMode = accessTokenCommand.SessionMode
	result, err := svr.getToken(*loginToken)
	return result["token"], err
}

func (svr AuthService) RefreshAuthAccessToken(refreshTokenCommand *command.RefreshTokenCommand) (interface{}, error) {
	if err := refreshTokenCommand.ValidateCommand(); err != nil {
		return nil, domain.NewApplicationError(domain.InvalidRefreshToken)
	}
	loginToken := domain.LoginToken{}
	err := loginToken.ParseToken(refreshTokenCommand.RefreshToken)
	if err != nil {
		return nil, domain.NewApplicationError(domain.InvalidRefreshToken)
	}
	//redis缓存
	tokenCache := cache.LoginTokenCache{}
	refreshToken, err := tokenCache.GetRefreshToken(loginToken.Account, loginToken.Platform)
	if err != nil {
		log.Logger.Debug(err.Error())
		return nil, domain.NewApplicationError(domain.InvalidRefreshToken)
	}
	if refreshToken != refreshTokenCommand.RefreshToken {
		return nil, domain.NewApplicationError(domain.InvalidRefreshToken)
	}

	token, err := svr.getToken(loginToken)
	if err != nil {
		return nil, domain.NewApplicationError(domain.InvalidRefreshToken)
	}
	return map[string]interface{}{
		"access": token["token"],
	}, err
}

//GetUserMenus 获取用户信息
func (svr AuthService) GetUserInfo(userInfoCommand *command.UserInfoCommand) (interface{}, error) {
	user, err := svr.getUserInfo(userInfoCommand.Operator)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return map[string]interface{}{
		"user": user,
	}, nil
}

//GetUserMenus 获取用户信息-额外的数据
func (svr AuthService) GetFavoriteMenus(userInfoCommand *command.UserInfoCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		userInfoCommand.Operator)
	resultUser, err := creationUserGateway.UserGet(allied_creation_user.ReqGetUser{
		UserId: int(userInfoCommand.Operator.UserId),
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return map[string]interface{}{
		"favoriteMenus": resultUser.FavoriteMenus,
	}, nil
}

//GetUserMenus 获取用户菜单
func (svr AuthService) GetUserMenus(userMenusCommand *command.UserMenusCommand) (interface{}, error) {
	if userMenusCommand.Operator.UserId == 0 {
		return map[string]interface{}{
			"accessMenus": struct{}{},
		}, nil
	}
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		userMenusCommand.Operator)
	resultMenu, err := creationUserGateway.UserAccessMenus(allied_creation_user.ReqUserAccessMenus{
		UserId:         int(userMenusCommand.Operator.UserId),
		MenuCategory:   userMenusCommand.MenuCategory,
		ALLDisableMenu: userMenusCommand.ALLDisableMenu,
		OrgId:          userMenusCommand.Operator.OrgId,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return map[string]interface{}{
		"accessMenus": resultMenu.Menus,
	}, nil
}

//GetUserMenus 获取用户组织
func (svr AuthService) GetUserOrg(userOrgCommand *command.UserOrgCommand) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(userOrgCommand.Operator)
	result, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
		Offset:       0,
		Limit:        100,
		UserBaseId:   userOrgCommand.Operator.UserBaseId,
		UserType:     domain.UserTypeEmployee,
		EnableStatus: domain.UserStatusEnable,
		PullRealTime: true,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	var res = make([]interface{}, 0)
	for i := range result.Users {
		for j := range result.Users[i].UserOrg {
			org := result.Users[i].UserOrg[j]
			res = append(res, map[string]interface{}{
				"orgId":   org.OrgID,
				"orgName": org.OrgName,
			})
		}
	}
	return map[string]interface{}{
		"orgs": res,
	}, nil
}

//OrgSwitch 组织切换
func (svr AuthService) OrgSwitch(switchOrgCommand *command.SwitchOrgCommand) (interface{}, error) {
	if err := switchOrgCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	loginToken := domain.LoginToken{}
	err := loginToken.ParseToken(switchOrgCommand.Operator.Token)
	if err != nil {
		return nil, domain.NewApplicationError(domain.InvalidAccessToken)
	}
	loginToken.OrgId = switchOrgCommand.OrgId
	token, err := svr.getToken(loginToken)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	var userId int64
	if v, ok := token["userId"]; ok {
		if vInt, ok := v.(int); !ok || vInt == 0 {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, "用户不存在")
		} else {
			userId = int64(vInt)
		}
	}
	user, err := svr.getUserInfo(domain.Operator{UserId: userId, OrgId: loginToken.OrgId})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		switchOrgCommand.Operator)
	resultMenu, err := creationUserGateway.UserAccessMenus(allied_creation_user.ReqUserAccessMenus{
		UserId: int(userId),
		OrgId:  switchOrgCommand.OrgId,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	var res = map[string]interface{}{
		"user":        user,
		"accessMenus": resultMenu.Menus,
		"access":      token["token"],
	}
	return res, nil
}

// CompanySignUp 企业注册
func (svr AuthService) CompanySignUp(companySignUpCommand *command.CompanySignUpCommand) (interface{}, error) {
	smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
	err := smsServeGateway.CheckSmsCode(companySignUpCommand.Phone, companySignUpCommand.SmsCode)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	_, err = creationUserGateway.AuthCompanySignUp(allied_creation_user.ReqAuthCompanySignUp{
		CompanyName:      companySignUpCommand.CompanyName,
		Phone:            companySignUpCommand.Phone,
		Password:         companySignUpCommand.Password,
		Contacts:         companySignUpCommand.Contacts,
		IndustryCategory: companySignUpCommand.IndustryCategory,
		Scale:            companySignUpCommand.Scale,

		LegalPerson:                companySignUpCommand.LegalPerson,
		SocialCreditCode:           companySignUpCommand.SocialCreditCode,
		BusinessLicenseAttachments: companySignUpCommand.BusinessLicenseAttachments,
		BusinessLicenseAddress:     companySignUpCommand.BusinessLicenseAddress,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return companySignUpCommand, err
}

func (svr AuthService) UserSignUp(signUpCommand *command.UserSignUpCommand) (interface{}, error) {
	if err := signUpCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
	err := smsServeGateway.CheckSmsCode(signUpCommand.Phone, signUpCommand.SmsCode)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	_, err = creationUserGateway.AuthUserSignUp(allied_creation_user.ReqAuthUserSignUp{
		Name:     signUpCommand.Name,
		Phone:    signUpCommand.Phone,
		Password: signUpCommand.Password,
		Referrer: signUpCommand.Referrer,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return signUpCommand, err
}

// ResetPassword  重置密码(找回密码)
func (svr AuthService) ResetPassword(resetPasswordCommand *command.ResetPasswordCommand) (interface{}, error) {
	if err := resetPasswordCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	var phone = resetPasswordCommand.Phone
	if len(resetPasswordCommand.SmsCode) > 0 {
		smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
		err := smsServeGateway.CheckSmsCode(resetPasswordCommand.Phone, resetPasswordCommand.SmsCode)
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
		}
	} else {
		pcc := cache.PhoneCheckCache{}
		var item = &cache.PhoneCheckItem{}
		if err := pcc.Get(resetPasswordCommand.SmsCodeIdentity, item); err != nil {
			log.Logger.Error(err.Error())
			return nil, application.ThrowError(application.BUSINESS_ERROR, "验证码已失效")
		}
		phone = item.Phone
	}

	// 2.重置密码
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	result, err := creationUserGateway.AuthResetPassword(allied_creation_user.ReqAuthResetPassword{
		Phone:    phone,
		Password: resetPasswordCommand.Password,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	return result, err
}

func (svr AuthService) getUserInfo(operator domain.Operator) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(
		operator)

	// 个人用户登录
	if operator.UserId == 0 && len(operator.Phone) != 0 {
		resultUser, err := creationUserGateway.AuthUserBaseInfo(allied_creation_user.ReqAuthUserBase{
			Account: operator.Phone,
		})
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
		}
		var user = map[string]interface{}{
			"userId": resultUser.UserID,
			//"userOpenId": fmt.Sprintf("%v",resultUser.UserBaseID),
			"userInfo": map[string]interface{}{
				"userName":   resultUser.UserInfo.UserName,
				"userPhone":  resultUser.UserInfo.Phone,
				"userAvatar": resultUser.UserInfo.Avatar,
				"email":      resultUser.UserInfo.Email,
			},
			"department": struct{}{},
			"company":    map[string]interface{}{},
			"im":         resultUser.Im,
			"org":        struct{}{},
		}
		return user, nil
	}
	// 企业用户登录
	resultUser, err := creationUserGateway.UserGet(allied_creation_user.ReqGetUser{
		UserId: int(operator.UserId),
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}

	var user = map[string]interface{}{
		"userId":   resultUser.UserId,
		"userType": resultUser.UserType,
		"userCode": resultUser.UserCode,
		"userInfo": map[string]interface{}{
			"userName":   resultUser.UserInfo.UserName,
			"userPhone":  resultUser.UserInfo.Phone,
			"userAvatar": resultUser.UserInfo.Avatar,
			"userCode":   resultUser.UserInfo.UserCode,
			"email":      resultUser.UserInfo.Email,
		},
		"department":    resultUser.Department,
		"im":            resultUser.IM,
		"favoriteMenus": resultUser.FavoriteMenus,
	}
	if operator.OrgId > 0 {
		resultOrg, err := creationUserGateway.OrgGet(allied_creation_user.ReqOrgGet{
			OrgId: int(operator.OrgId),
		})
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
		}
		user["org"] = map[string]interface{}{
			"orgId":     resultOrg.OrgID,
			"orgName":   resultOrg.OrgName,
			"orgCode":   resultOrg.OrgCode,
			"companyId": resultOrg.CompanyID,
		}
	}
	if resultUser.Company != nil {
		user["company"] = map[string]interface{}{
			"companyId":   resultUser.Company.CompanyId,
			"companyName": resultUser.Company.CompanyName,
			"logo":        resultUser.Company.Logo,
			"systemName":  resultUser.Company.SystemName,
			"address":     resultUser.Company.Address,
		}
	}
	return user, nil
}

func (svr AuthService) getToken(loginToken domain.LoginToken) (map[string]interface{}, error) {
	// 1.匹配账号对应的用户
	currentUser, err := svr.matchUserV2(&loginToken)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}

	// 2. 更新LoginAccess
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var loginAccessRepository domain.LoginAccessRepository
	if loginAccessRepository, err = factory.CreateLoginAccessRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	_, lAccess, err := loginAccessRepository.Find(map[string]interface{}{
		"account":  loginToken.Account,
		"platform": loginToken.Platform,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	var currentAccess = &domain.LoginAccess{CreatedTime: time.Now()}
	if len(lAccess) > 0 {
		currentAccess = lAccess[0]
	}

	if _, err = currentAccess.ResetLoginAccess(loginToken); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	//存数据库
	if _, err = loginAccessRepository.Save(currentAccess); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	//redis缓存
	tokenCache := cache.LoginTokenCache{}
	if err = tokenCache.SaveAccessToken(currentAccess); err != nil {
		return nil, err
	}
	if err = tokenCache.SaveRefreshToken(currentAccess); err != nil {
		return nil, err
	}

	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	nowTime := time.Now().Unix()
	token := map[string]interface{}{
		"refreshToken": currentAccess.RefreshToken,
		"accessToken":  currentAccess.AccessToken,
		"expiresIn":    currentAccess.AccessExpired - nowTime,
	}
	return map[string]interface{}{
		"token":  token,
		"userId": currentUser.UserId,
	}, nil
}

func (svr AuthService) matchUser(loginToken *domain.LoginToken) (*allied_creation_user.UserDetail, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	userSearchResult, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
		Phone:        loginToken.Account,
		UserType:     domain.UserTypeEmployee,
		EnableStatus: domain.UserStatusEnable,
	})
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "用户信息获取失败,"+err.Error())
	}
	// 1 . 判定当前凭证的companyId,OrganizationId 是否在用户列表中
	var currentOrgIsOK bool
	var currentUser allied_creation_user.UserDetail
loopUser1:
	for _, v := range userSearchResult.Users {
		for _, vv := range v.UserOrg {
			if vv.OrgID == int(loginToken.OrgId) && v.Company.Status == domain.CompanyAuthenticated {
				currentOrgIsOK = true
				currentUser = v
				break loopUser1
			}
		}
	}
	if !currentOrgIsOK {
	loopUser2:
		for _, v := range userSearchResult.Users {
			for _, vv := range v.UserOrg {
				loginToken.OrgId = int64(vv.OrgID)
				currentOrgIsOK = true
				currentUser = v
				break loopUser2
			}
		}
	}
	if !currentOrgIsOK && loginToken.Platform == domain.LoginPlatformWeb {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, "登录的公司组织不可用")
	}
	if currentOrgIsOK {
		loginToken.UserId = int64(currentUser.UserId)
		loginToken.UserBaseId = int64(currentUser.UserBaseId)
		loginToken.CompanyId = int64(currentUser.Company.CompanyId)
		var orgIds []int64
		for i := range currentUser.UserOrg {
			orgIds = append(orgIds, int64(currentUser.UserOrg[i].OrgID))
		}
		loginToken.OrgIds = orgIds
	}

	// 个人登录
	if !currentOrgIsOK { //|| len(userSearchResult.Users) == 0
		userBase, err := creationUserGateway.AuthUserBaseInfo(allied_creation_user.ReqAuthUserBase{
			Account: loginToken.Account,
		})
		if err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, "账号不存在")
		}
		loginToken.UserId = int64(userBase.UserID)
		loginToken.UserBaseId = int64(userBase.UserBaseID)
		if userBase.UserBaseID > 0 {
			cooperationUsers, _ := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
				UserBaseId:   int64(userBase.UserBaseID),
				UserType:     domain.UserTypeCooperation,
				EnableStatus: domain.UserStatusEnable,
			})
			if len(cooperationUsers.Users) > 0 {
				loginToken.CompanyId = int64(cooperationUsers.Users[0].Company.CompanyId)
				loginToken.UserId = int64(cooperationUsers.Users[0].UserId)
				loginToken.OrgId = int64(cooperationUsers.Users[0].Org.OrgId)
				currentUser = cooperationUsers.Users[0]
			}
		}
	}
	return &currentUser, nil
}

func (svr AuthService) matchUserV2(loginToken *domain.LoginToken) (*allied_creation_user.UserDetail, error) {
	var users []allied_creation_user.UserDetail
	var currentUser *allied_creation_user.UserDetail
	var defaultUser *allied_creation_user.UserDetail
	var ok bool
	var mapOrgUser = make(map[int]*allied_creation_user.UserDetail)
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
	switch loginToken.Platform {
	case domain.LoginPlatformWeb:
		userSearchResult, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
			Phone:        loginToken.Account,
			UserType:     domain.UserTypeEmployee,
			EnableStatus: domain.UserStatusEnable,
		})
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, "用户信息获取失败,"+err.Error())
		}
		users = userSearchResult.Users
	case domain.LoginPlatformApp:
		userSearchResult, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
			Phone:        loginToken.Account,
			UserType:     domain.UserTypeEmployee | domain.UserTypeCooperation | domain.UserTypeVisitor,
			EnableStatus: domain.UserStatusEnable,
		})
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, "用户信息获取失败,"+err.Error())
		}
		users = userSearchResult.Users
	case domain.LoginPlatformOperatorWeb:
		userSearchResult, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
			Phone:        loginToken.Account,
			UserType:     domain.UserTypeOperationAdmin,
			EnableStatus: domain.UserStatusEnable,
		})
		if err != nil {
			return nil, application.ThrowError(application.BUSINESS_ERROR, "用户信息获取失败,"+err.Error())
		}
		users = userSearchResult.Users
	}
	if len(users) == 0 {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, "账号不存在")
	}

	for index, user := range users {
		if user.Company != nil && user.Company.Status != domain.CompanyAuthenticated {
			continue
		}
		for _, userOrg := range user.UserOrg {
			mapOrgUser[userOrg.OrgID] = &users[index]
			if defaultUser == nil {
				defaultUser = &users[index]
			}
		}
	}
	if defaultUser == nil {
		defaultUser = &users[0]
	}
	//切换组织
	if loginToken.OrgId != 0 {
		if currentUser, ok = mapOrgUser[int(loginToken.OrgId)]; !ok { //&& loginToken.Platform == domain.LoginPlatformWeb
			return nil, application.ThrowError(application.TRANSACTION_ERROR, "登录的公司组织不可用")
		}
	}
	// 使用默认账号
	if currentUser == nil {
		currentUser = defaultUser
	}

	SetLoginToken(loginToken, currentUser)

	return currentUser, nil
}

func SetLoginToken(loginToken *domain.LoginToken, currentUser *allied_creation_user.UserDetail) {
	// 当前登录的公司用户信息
	loginToken.UserId = int64(currentUser.UserId)
	loginToken.UserBaseId = int64(currentUser.UserBaseId)
	if currentUser.Company != nil {
		loginToken.CompanyId = int64(currentUser.Company.CompanyId)
	}

	// 关联的组织
	var orgIds []int64
	for i := range currentUser.UserOrg {
		orgIds = append(orgIds, int64(currentUser.UserOrg[i].OrgID))
		// 默认组织
		if loginToken.OrgId == 0 {
			loginToken.OrgId = int64(currentUser.UserOrg[i].OrgID)
		}
	}
	loginToken.OrgIds = orgIds
}

//GetCompanyOrgsByUser 获取登录用户的公司组织列表
func (svr AuthService) GetCompanyOrgsByUser(queryParam *query.GetCompanyOrgsByUserQuery) (interface{}, error) {
	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(queryParam.Operator)
	result, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
		Phone:        queryParam.Operator.Phone,
		UserType:     domain.UserTypeEmployee,
		PullRealTime: true,
		EnableStatus: domain.UserStatusEnable,
	})
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	var (
		companys   []dto.CompanyItem
		orgs       []dto.OrgItem
		mapCompany = make(map[int]interface{})
	)

	for i := range result.Users {
		user := result.Users[i]
		if _, ok := mapCompany[user.Company.CompanyId]; !ok && len(user.UserOrg) > 0 {
			companys = append(companys, dto.CompanyItem{
				CompanyId:   user.Company.CompanyId,
				CompanyName: user.Company.CompanyName,
			})
			if user.Company.Status != domain.CompanyAuthenticated {
				continue
			}
		}
		for j := range user.UserOrg {
			org := user.UserOrg[j]
			orgs = append(orgs, dto.OrgItem{
				OrganizationId:   org.OrgID,
				OrganizationName: org.OrgName,
				CompanyId:        user.Company.CompanyId,
			})
		}
	}

	data := map[string]interface{}{
		"companys":      companys,
		"organizations": orgs,
	}
	return data, nil
}

//GetQrcode 获取扫码登录需要的二维码
func (svr AuthService) GetQrcode() (interface{}, error) {
	qrcodeMessage := domain.QrcodeMessage{}
	_, err := qrcodeMessage.Init()
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	qrCache := cache.LoginQrcodeCache{}
	err = qrCache.Save(qrcodeMessage)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	data := map[string]interface{}{
		"key": qrcodeMessage.Token,
	}
	return data, nil
}

//CheckSmsCode 验证手机短信验证码
func (svr AuthService) CheckSmsCode(smsCodeCommand *command.CheckSmsCodeCommand) (interface{}, error) {
	smsServeGateway := sms_serve.NewHttplibHttplibSmsServe()
	err := smsServeGateway.CheckSmsCode(smsCodeCommand.Phone, smsCodeCommand.SmsCode)
	if err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	uid := uuid.New()
	pcc := cache.PhoneCheckCache{}
	if err := pcc.Add(uid.String(), cache.PhoneCheckItem{
		Phone:           smsCodeCommand.Phone,
		SmsCodeIdentity: uid.String(),
		Action:          smsCodeCommand.Action,
	}); err != nil {
		log.Logger.Error(err.Error())
		return nil, application.ThrowError(application.BUSINESS_ERROR, "系统错误")
	}
	return map[string]interface{}{
		"smsCodeIdentity": uid.String(),
	}, nil
}

func (svr *AuthService) CaptchaInit(request *query.CaptchaInitRequest) (interface{}, error) {
	var rsp map[string]interface{}
	var err error

	lib := geetest.NewGeetestLib(captchaID, privateKey, 2*time.Second)
	status, responseBt := lib.PreProcess("", request.UserIp)
	var geetestRsp geetest.FailbackRegisterRespnse
	json.Unmarshal(responseBt, &geetestRsp)
	rspData := map[string]interface{}{
		"success":    geetestRsp.Success,
		"gt":         geetestRsp.GT,
		"challenge":  geetestRsp.Challenge,
		"newCaptcha": geetestRsp.NewCaptcha,
	}
	if status == 0 {
		return nil, application.ThrowError(application.BUSINESS_ERROR, "获取图形验证码失败,请重试")
	}

	rsp = rspData
	return rsp, err
}

/*******************运营登录**********************/
//AuthLogin 用户登录
func (svr AuthService) AuthAdminLogin(loginCommand *command.LoginPwdCommand) (interface{}, error) {
	login := &command.LoginCommand{
		GrantType:     "signInPassword",
		Phone:         loginCommand.Username,
		Password:      loginCommand.Password,
		SessionMode:   loginCommand.SessionMode,
		DeviceType:    loginCommand.DeviceType,
		LoginPlatform: domain.LoginPlatformOperatorWeb,
	}
	return svr.AuthLogin(login)
}

//AuthLogin 用户登录
//func (svr AuthService) AuthAdminLoginBak(loginCommand *command.LoginPwdCommand) (interface{}, error) {
//	if err := loginCommand.ValidateCommand(); err != nil {
//		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
//	}
//	if len(loginCommand.Username) == 0 {
//		return nil, application.ThrowError(application.BUSINESS_ERROR, "账号不存在")
//	}
//	creationUserGateway := allied_creation_user.NewHttplibAlliedCreationUser(domain.Operator{})
//	users, err := creationUserGateway.UserSearch(allied_creation_user.ReqUserSearch{
//		UserType: domain.UserTypeOperationAdmin,
//		Phone:    loginCommand.Username,
//	})
//	if err != nil {
//		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
//	}
//	if len(users.Users) == 0 {
//		return nil, application.ThrowError(application.BUSINESS_ERROR, "账号不存在")
//	}
//	login := &command.LoginCommand{
//		GrantType:   "signInPassword",
//		Phone:       loginCommand.Username,
//		Password:    loginCommand.Password,
//		SessionMode: loginCommand.SessionMode,
//		DeviceType:  loginCommand.DeviceType,
//	}
//	if len(loginCommand.CaptchaChallenge) > 0 {
//		geetest := geetest.NewGeetestLib(captchaID, privateKey, 2*time.Second)
//		validateResult := geetest.SuccessValidate(loginCommand.CaptchaChallenge, loginCommand.CaptchaValidate, loginCommand.CaptchaSeccode, "", "")
//		if !validateResult {
//			log.Logger.Error("validate captcha fail")
//		}
//	}
//	return svr.AuthLogin(login)
//}