package auth

import (
	"context"
	"git.noahlan.cn/n-admin/n-admin-server/dal/errx"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/types/core"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus/msg"
	"git.noahlan.cn/noahlan/ntool/nrandom"
	"git.noahlan.cn/noahlan/ntool/nstd/tea"

	"git.noahlan.cn/n-admin/n-admin-server/api/internal/svc"
	"git.noahlan.cn/n-admin/n-admin-server/api/internal/types"

	"net/http"
)

type RegisterLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	r      *http.Request
}

func NewRegisterLogic(r *http.Request, ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
	return &RegisterLogic{
		r:      r,
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.BaseID, err error) {
	if err := l.svcCtx.Captcha.Verify(req.CaptchaId, req.Captcha, true); err != nil {
		return nil, err
	}
	// verify code
	if req.Code != nil {
		if req.PhoneNumber != nil && *req.PhoneNumber != "" {
			code, _, err := l.svcCtx.CodeCache.GetCachedCode(*req.PhoneNumber, types.CodeSourceSms, types.SmsCodeTypeRegister)
			if err != nil {
				return nil, nstatus.NewApiInternalErr(msg.CacheError)
			}
			if *req.Code != code {
				return nil, nstatus.NewBizErrWithCode(errx.WrongCode)
			}
		} else if req.Email != nil && *req.Email != "" {
			code, _, err := l.svcCtx.CodeCache.GetCachedCode(*req.PhoneNumber, types.CodeSourceEmail, types.SmsCodeTypeRegister)
			if err != nil {
				return nil, nstatus.NewApiInternalErr(msg.CacheError)
			}
			if *req.Code != code {
				return nil, nstatus.NewBizErrWithCode(errx.WrongCode)
			}
		}
	}

	// username not empty
	if req.Username == nil {
		req.Username = tea.String(nrandom.RandString(6))
	}

	user, err := register(l.ctx, l.svcCtx, &core.UserInfo{
		Username:    *req.Username,
		PhoneNumber: req.PhoneNumber,
		Email:       req.Email,
		Password:    req.Credentials,
	})
	if err != nil {
		return nil, err
	}
	resp = &types.BaseID{ID: user.ID}
	return
}
