package user

import (
	"backend/internal/svc"
	"backend/internal/types"
	errs "backend/pkg/library/errors"
	mbr "backend/pkg/member/domain/member"
	member "backend/pkg/member/domain/usecase"
	"backend/pkg/permission/domain/token"
	"context"

	"github.com/zeromicro/go-zero/core/logx"
)

type SubmitVerificationCodeLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewSubmitVerificationCodeLogic 交驗證碼以完成驗證
func NewSubmitVerificationCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubmitVerificationCodeLogic {
	return &SubmitVerificationCodeLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SubmitVerificationCodeLogic) SubmitVerificationCode(req *types.SubmitVerificationCodeReq) (*types.RespOK, error) {
	acc := ""
	ct := mbr.GenerateCodeTypeEmail
	switch req.Purpose {
	case "email_verification":
		if !isValidEmail(req.Account) {
			return nil, errs.InputInvalidFormatError("email is invalid")
		}
		acc = req.Account
	case "phone_verification":
		phone, isPhone := normalizeTaiwanMobile(req.Account)
		if !isPhone {
			return nil, errs.InputInvalidFormatError("phone number is invalid")
		}
		acc = phone
		ct = mbr.GenerateCodeTypePhone
	default:
		return &types.RespOK{}, errs.InputInvalidRangeError("")
	}

	// 先驗證，不刪除
	if err := l.svcCtx.AccountUC.CheckRefreshCode(l.ctx, member.VerifyRefreshCodeRequest{
		VerifyCode: req.VerifyCode,
		LoginID:    acc,
		CodeType:   ct,
	}); err != nil {
		e := errs.AuthForbiddenError("failed to get verify code").Wrap(err)

		return nil, e
	}
	uid := token.UID(l.ctx)
	switch req.Purpose {
	case "email_verification":
		err := l.svcCtx.AccountUC.BindVerifyEmail(l.ctx, uid, acc)
		if err != nil {
			return nil, err
		}
	case "phone_verification":
		err := l.svcCtx.AccountUC.BindVerifyPhone(l.ctx, uid, acc)
		if err != nil {
			return nil, err
		}
	default:
		return &types.RespOK{}, errs.InputInvalidRangeError("")
	}

	err := l.svcCtx.AccountUC.UpdateStatus(l.ctx, member.UpdateStatusRequest{
		UID:    uid,
		Status: mbr.AccountStatusActive,
	})
	if err != nil {
		return nil, err
	}

	// 真的刪除
	_ = l.svcCtx.AccountUC.VerifyRefreshCode(l.ctx, member.VerifyRefreshCodeRequest{
		VerifyCode: req.VerifyCode,
		LoginID:    acc,
		CodeType:   ct,
	})

	return &types.RespOK{}, nil
}
