package auth

import (
	"backend/internal/domain"
	errs "backend/pkg/library/errors"
	"backend/pkg/member/domain/member"
	"backend/pkg/member/domain/usecase"
	"backend/pkg/permission/domain/entity"

	"context"
	"fmt"

	"backend/internal/svc"
	"backend/internal/types"

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

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

// NewResetPasswordLogic 執行密碼重設
func NewResetPasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ResetPasswordLogic {
	return &ResetPasswordLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ResetPasswordLogic) ResetPassword(req *types.ResetPasswordReq) (*types.RespOK, error) {
	// 驗證密碼，兩次密碼要一致
	if req.Password != req.PasswordConfirm {
		return nil, errs.InputInvalidFormatError("password confirmation does not match")
	}

	// 驗證碼
	err := l.svcCtx.AccountUC.VerifyRefreshCode(l.ctx, usecase.VerifyRefreshCodeRequest{
		LoginID:    req.Identifier,
		CodeType:   member.GenerateCodeTypeForgetPassword,
		VerifyCode: req.VerifyCode,
	})
	if err != nil {
		// 表使沒有這驗證碼
		return nil, errs.AuthForbiddenError("failed to get verify code")
	}

	info, err := l.svcCtx.AccountUC.GetUserAccountInfo(l.ctx, usecase.GetUIDByAccountRequest{Account: req.Identifier})
	if err != nil {
		return nil, err
	}

	if info.Data.Platform != member.Digimon {
		return nil, errs.AuthForbiddenError("invalid platform")
	}

	// 更新
	err = l.svcCtx.AccountUC.UpdateUserToken(l.ctx, usecase.UpdateTokenRequest{
		Account:  req.Identifier,
		Token:    req.Password,
		Platform: member.Digimon.ToInt64(),
	})
	if err != nil {
		return nil, err
	}

	rk := domain.GenerateVerifyCodeRedisKey.With(
		fmt.Sprintf("%s-%d", req.Identifier, member.GenerateCodeTypeForgetPassword),
	).ToString()

	_, _ = l.svcCtx.Redis.Del(rk)

	ac, err := l.svcCtx.AccountUC.GetUIDByAccount(l.ctx, usecase.GetUIDByAccountRequest{Account: req.Identifier})
	if err != nil {
		return nil, err
	}

	err = l.svcCtx.TokenUC.CancelTokens(l.ctx, entity.DoTokenByUIDReq{UID: ac.UID})
	if err != nil {
		return nil, err
	}

	// 返回成功響應
	return &types.RespOK{}, nil
}
