package user

import (
	"context"
	"strings"

	"github.com/gin-gonic/gin"
	commonLogic "github.com/perfect-panel/server/internal/logic/common"
	"github.com/perfect-panel/server/internal/logic/public/user"
	"github.com/perfect-panel/server/internal/svc"
	"github.com/perfect-panel/server/internal/types"
	"github.com/perfect-panel/server/pkg/authmethod"
	"github.com/perfect-panel/server/pkg/constant"
	"github.com/perfect-panel/server/pkg/result"
	"github.com/perfect-panel/server/pkg/xerr"
	"github.com/pkg/errors"
)

// DeleteAccountHandler 注销账号处理器
// 仅执行注销登录与家庭退出/解散，不删除账号主体。
// 需携带邮箱验证码，验证通过后执行。
type deleteAccountReq struct {
	Email string `json:"email" binding:"required,email"` // 用户邮箱
	Code  string `json:"code" binding:"required"`        // 邮箱验证码
}

func DeleteAccountHandler(serverCtx *svc.ServiceContext) gin.HandlerFunc {
	return func(c *gin.Context) {
		var req deleteAccountReq
		if err := c.ShouldBindJSON(&req); err != nil {
			result.ParamErrorResult(c, err)
			return
		}

		// 统一处理邮箱格式：转小写并去空格，与发送验证码逻辑保持一致
		req.Email = strings.ToLower(strings.TrimSpace(req.Email))

		// 校验邮箱验证码（统一走公共验证码校验器，支持 delete_account/security 场景兼容）
		if err := verifyEmailCode(c.Request.Context(), serverCtx, req.Email, req.Code); err != nil {
			result.HttpResult(c, nil, err)
			return
		}

		l := user.NewDeleteAccountLogic(c.Request.Context(), serverCtx)
		resp, err := l.DeleteAccountAll()
		result.HttpResult(c, resp, err)
	}
}

// verifyEmailCode 校验邮箱验证码
// 1. 统一复用 common checker
// 2. 强制 consume=true（最终业务操作做一次性消费）
// 3. 兼容历史 security 场景验证码（allow fallback）
func verifyEmailCode(ctx context.Context, serverCtx *svc.ServiceContext, email string, code string) error {
	l := commonLogic.NewCheckVerificationCodeLogic(ctx, serverCtx)
	resp, err := l.CheckVerificationCodeWithBehavior(&types.CheckVerificationCodeRequest{
		Method:  authmethod.Email,
		Account: email,
		Code:    strings.TrimSpace(code),
		Type:    uint8(constant.DeleteAccount),
	}, commonLogic.VerifyCodeCheckBehavior{
		Source:             "delete_account",
		Consume:            true,
		AllowSceneFallback: true,
	})
	if err != nil {
		return err
	}

	if resp == nil || !resp.Status {
		return errors.Wrapf(xerr.NewErrCode(xerr.VerifyCodeError), "verification code error or expired")
	}

	return nil
}
