package auth

import (
	"fmt"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/factory"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/partnerInfo/query"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/partnerInfo/service"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/svr"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/utils"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/protocol"
	"strings"
	"time"
)

func Login(header *protocol.RequestHeader, request *protocol.LoginRequest) (rsp *protocol.LoginResponse, err error) {
	var (
		PartnerInfoService             = service.NewPartnerInfoService(nil)
		partnerInfo                    *domain.PartnerInfo
		result                         bool = false
		transactionContext, _               = factory.CreateTransactionContext(nil)
		PartnerSubAccountRepository, _      = factory.CreatePartnerSubAccountRepository(transactionContext)
		partnerSubAccount              *domain.PartnerSubAccount
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			transactionContext.RollbackTransaction()
			return
		}
		err = transactionContext.CommitTransaction()
	}()
	rsp = &protocol.LoginResponse{}
	if partnerInfo, err = PartnerInfoService.GetPartnerInfo(&query.GetPartnerInfoQuery{Account: request.Phone}); err != nil {
		//子账号
		if partnerSubAccount, err = PartnerSubAccountRepository.FindOne(map[string]interface{}{"account": request.Phone}); err == nil {
			partnerInfo = &domain.PartnerInfo{
				Id:       partnerSubAccount.PartnerId,
				Account:  partnerSubAccount.Account,
				Password: partnerSubAccount.Password,
			}
		} else {
			err = protocol.NewErrWithMessage(502, err) //账号不存在
			return
		}
	}
	switch request.GrantType {
	case protocol.LoginByPassword:
		if len(partnerInfo.Password) == 0 {
			err = protocol.NewCustomMessage(1, "密码不能为空!")
			return
		}
		if result = strings.EqualFold(partnerInfo.Password, request.Password); !result {
			err = protocol.NewCustomMessage(1, "密码输入有误!")
			return
		}
		break
	case protocol.LoginBySmsCode:
		if _, err = CheckSmsCode(request.Phone, request.Captcha); err != nil {
			return
		}
		break
	}
	rsp.AuthCode, _ = utils.GenerateToken(partnerInfo.Id, protocol.AuthCodeExpire*time.Second)
	return
}

func SmsCode(request *protocol.SmsCodeRequest) (rsp *protocol.SmsCodeResponse, err error) {
	var data map[string]interface{}
	sms := svr.NewHttplibMmmSmsApiServiceGateway()
	data, err = sms.SendSms(request.Phone)
	rsp = &protocol.SmsCodeResponse{}
	if err != nil {
		if msg, ok := data["msg"]; ok {
			err = protocol.NewCustomMessage(1, msg.(string))
		}
		return
	}
	return
}

func AccessToken(request *protocol.AccessTokenRequest) (rsp *protocol.AccessTokenResponse, err error) {
	var (
		claim *utils.UserTokenClaims
	)
	rsp = &protocol.AccessTokenResponse{}
	if claim, err = utils.ParseJWTToken(request.AuthCode); err != nil {
		err = protocol.NewErrWithMessage(4139, err)
		return
	}
	if claim.UserId <= 0 {
		err = protocol.NewErrWithMessage(1, fmt.Errorf("jwt authCode (%v) valid", request.AuthCode))
		return
	}
	rsp.AccessToken, _ = utils.GenerateToken(claim.UserId, protocol.TokenExpire*time.Second)
	rsp.RefreshToken, _ = utils.GenerateToken(claim.UserId, protocol.RefreshTokenExipre*time.Second)
	rsp.ExpiresIn = protocol.TokenExpire
	return
}

func RefreshToken(request *protocol.RefreshTokenRequest) (rsp *protocol.RefreshTokenResponse, err error) {
	var (
		claim *utils.UserTokenClaims
	)
	rsp = &protocol.RefreshTokenResponse{}
	if claim, err = utils.ParseJWTToken(request.RefreshToken); err != nil {
		err = protocol.NewErrWithMessage(4139, err)
		return
	}
	if claim.UserId <= 0 {
		err = protocol.NewErrWithMessage(1, fmt.Errorf("jwt refrshToken (%v) valid", request.RefreshToken))
		return
	}
	rsp.AccessToken, _ = utils.GenerateToken(claim.UserId, protocol.TokenExpire*time.Second)
	rsp.RefreshToken, _ = utils.GenerateToken(claim.UserId, protocol.RefreshTokenExipre*time.Second)
	rsp.ExpiresIn = protocol.TokenExpire
	return
	return
}

//验证短信验证码 T
func CheckSmsCode(phone, code string) (result bool, err error) {
	sms := svr.NewHttplibMmmSmsApiServiceGateway()
	var data map[string]interface{}
	data, err = sms.CheckSmsCode(phone, code)
	if err != nil {
		if msg, ok := data["msg"]; ok {
			err = protocol.NewCustomMessage(1, msg.(string))
		}
		return
	}
	return
}

//验证手机号码(修改手机号码、重置密码的前一步)
func AuthCheckSmsCode(header *protocol.RequestHeader, request *protocol.AuthCheckSmsCodeRequest) (rsp *protocol.AuthCheckSmsCodeResponse, err error) {
	var ()
	if _, err = CheckSmsCode(request.Phone, request.Captcha); err != nil {
		return
	}
	rsp = &protocol.AuthCheckSmsCodeResponse{
		CaptchaCertificate: fmt.Sprintf("%v", utils.GenerateRangeNum(100000, 799999)),
	}
	return
}