package agent

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	"hm-server/app/main/api/internal/service"
	"hm-server/app/main/api/internal/svc"
	"hm-server/app/main/api/internal/types"
	"hm-server/app/main/model"
	"hm-server/common/ctxdata"
	"hm-server/common/xerr"
	"hm-server/pkg/lzkit/crypto"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/redis"
)

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

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

func (l *AgentRealNameLogic) AgentRealName(req *types.AgentRealNameReq) (resp *types.AgentRealNameResp, err error) {
	userID, err := ctxdata.GetUidFromCtx(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户ID失败, %v", err)
	}
	secretKey := l.svcCtx.Config.Encrypt.SecretKey
	encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "代理实名, 加密手机号失败: %v", err)
	}
	// 检查手机号是否在一分钟内已发送过验证码
	redisKey := fmt.Sprintf("%s:%s", "realName", encryptedMobile)
	cacheCode, err := l.svcCtx.Redis.Get(redisKey)
	if err != nil {
		if errors.Is(err, redis.Nil) {
			return nil, errors.Wrapf(xerr.NewErrMsg("验证码已过期"), "代理实名, 验证码过期: %s", encryptedMobile)
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "代理实名, 读取验证码redis缓存失败, mobile: %s, err: %+v", encryptedMobile, err)
	}
	if cacheCode != req.Code {
		return nil, errors.Wrapf(xerr.NewErrMsg("验证码不正确"), "代理实名, 验证码不正确: %s", encryptedMobile)
	}
	agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理信息失败, %v", err)
	}

	agentRealName, err := l.svcCtx.AgentRealNameModel.FindOneByAgentId(l.ctx, agent.Id)
	if err != nil && !errors.Is(err, model.ErrNotFound) {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取代理实名信息失败, %v", err)
	}

	if agentRealName != nil && agentRealName.Status == model.AgentRealNameStatusApproved {
		return nil, errors.Wrapf(xerr.NewErrMsg("代理实名信息已审核通过"), "代理实名信息已审核通过")
	}
	// 三要素验证
	threeVerification := service.ThreeFactorVerificationRequest{
		Name:   req.Name,
		IDCard: req.IDCard,
		Mobile: req.Mobile,
	}
	verification, err := l.svcCtx.VerificationService.ThreeFactorVerification(threeVerification)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "三要素验证失败: %v", err)
	}
	if !verification.Passed {
		return nil, errors.Wrapf(xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, verification.Err.Error()), "三要素验证不通过: %v", err)
	}
	agentRealName = &model.AgentRealName{
		AgentId:     agent.Id,
		Status:      model.AgentRealNameStatusApproved,
		Name:        req.Name,
		IdCard:      req.IDCard,
		ApproveTime: sql.NullTime{Time: time.Now(), Valid: true},
	}
	_, err = l.svcCtx.AgentRealNameModel.Insert(l.ctx, nil, agentRealName)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "添加代理实名信息失败, %v", err)
	}

	return &types.AgentRealNameResp{
		Status: agentRealName.Status,
	}, nil
}
