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

package auth

import (
	"context"

	"gateway/internal/svc"
	"gateway/internal/types"

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

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

func NewPasswordForgotLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PasswordForgotLogic {
	return &PasswordForgotLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *PasswordForgotLogic) PasswordForgot(req *types.PasswordForgotReq) (*types.PasswordForgotData, error) {
	if err := requireRegistrationDeps(l.svcCtx); err != nil {
		return nil, err
	}
	if req == nil {
		return nil, errb.InputMissingRequired("request body is required")
	}

	tenant, err := resolveTenant(l.ctx, l.svcCtx, req.TenantSlug)
	if err != nil {
		return nil, err
	}

	email := normalizeLoginEmail(req.Email)
	member, err := l.svcCtx.MemberProfile.GetByZitadelEmail(l.ctx, tenant.TenantID, email)
	if err != nil {
		if isMemberNotFound(err) {
			return nil, errb.ResNotFound("member", email)
		}
		return nil, err
	}
	if err := ensurePlatformNativePassword(member); err != nil {
		return nil, err
	}
	if err := ensurePasswordResetEligible(member.Status); err != nil {
		return nil, err
	}
	if member.ZitadelUserID == "" {
		return nil, errb.ResInvalidState("member has no zitadel identity")
	}

	target := email
	if member.ZitadelEmail != "" {
		target = normalizeLoginEmail(member.ZitadelEmail)
	}
	return sendPasswordResetOTP(l.ctx, l.svcCtx, tenant.TenantID, member.UID, target)
}
