// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.2

package email

import (
	"context"
	"encoding/json"
	"fmt"
	"juwan-backend/common/redisx"
	"time"

	"juwan-backend/app/email/api/internal/svc"
	"juwan-backend/app/email/api/internal/types"
	"juwan-backend/app/email/api/internal/utils"

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

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

// 发送邮箱验证码
func NewSendVerificationCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendVerificationCodeLogic {
	return &SendVerificationCodeLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SendVerificationCodeLogic) SendVerificationCode(req *types.SendVerificationCodeReq) (resp *types.SendVerificationCodeResp, err error) {
	if l.svcCtx.RedisCluster == nil {
		return nil, fmt.Errorf("redis not configured")
	}

	if l.svcCtx.EmailPusher == nil {
		return nil, fmt.Errorf("kafka pusher not configured")
	}

	code := utils.GenCode()
	requestID := uuid.NewString()

	redisKey := fmt.Sprintf(redisx.VCODE_KEY_PREFIX, requestID, req.Scene, req.Email)
	if exists, getErr := l.svcCtx.RedisCluster.Get(l.ctx, redisKey).Result(); getErr == nil && exists != "" {
		return nil, fmt.Errorf("verification code already sent, please wait before requesting a new one")
	}
	if setErr := l.svcCtx.RedisCluster.Set(l.ctx, redisKey, code, 60*time.Second).Err(); setErr != nil {
		return nil, setErr
	}

	payload := map[string]any{
		"type":      "verification_code",
		"requestId": requestID,
		"email":     req.Email,
		"scene":     req.Scene,
		"code":      code,
		"expireIn":  60,
	}
	messageBytes, marshalErr := json.Marshal(payload)
	if marshalErr != nil {
		return nil, marshalErr
	}

	if pushErr := l.svcCtx.EmailPusher.PushWithKey(l.ctx, req.Email, string(messageBytes)); pushErr != nil {
		return nil, pushErr
	}

	resp = &types.SendVerificationCodeResp{
		RequestId:   requestID,
		ExpireInSec: 60,
		Message:     "verification code send task submitted",
	}

	return
}
