package auth

import (
	"context"
	"database/sql"
	"encoding/hex"
	"math/rand"
	"strconv"
	"time"

	"qnc-server/app/main/api/internal/svc"
	"qnc-server/app/main/api/internal/types"
	"qnc-server/app/main/model"
	"qnc-server/common/xerr"
	"qnc-server/pkg/core/aliyun/cloudauth"
	"qnc-server/pkg/lzkit/crypto"

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

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

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

// 生成带前缀的随机OuterOrderNo（阿里云人脸验证单号）
func genOuterOrderNo() string {
	prefix := "FACE_"
	timestamp := time.Now().UnixNano()
	randNum := rand.Intn(1000000)
	return prefix + strconv.FormatInt(timestamp, 10) + strconv.Itoa(randNum)
}

func (l *InitFaceVerifyLogic) InitFaceVerify(req *types.InitFaceVerifyReq) (resp *types.InitFaceVerifyResp, err error) {
	order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
	}

	if order.Status != "paid" {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "订单未支付")
	}

	authorization, err := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, order.Id)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权信息失败: %v", err)
	}

	if authorization.Status != "pending" {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "授权信息状态不正确")
	}
	key, decodeErr := hex.DecodeString(l.svcCtx.Config.Encrypt.SecretKey)
	if decodeErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", decodeErr)
	}
	authorizationFaceBuilder := l.svcCtx.AuthorizationFaceModel.SelectBuilder().
		Where("authorization_id = ? AND status = ? AND certify_id != '' AND certify_url != ''",
			authorization.Id, model.AuthorizationStatusPending).
		OrderBy("create_time DESC").
		Limit(1)
	existingFaces, err := l.svcCtx.AuthorizationFaceModel.FindAll(l.ctx, authorizationFaceBuilder, "")
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询人脸认证记录失败: %v", err)
	}
	if len(existingFaces) > 0 {
		// 如果存在记录，直接返回最新的认证信息
		return &types.InitFaceVerifyResp{
			CertifyId:  existingFaces[0].CertifyId,
			CertifyUrl: existingFaces[0].CertifyUrl,
		}, nil
	}

	outerOrderNo := genOuterOrderNo()
	name, err := crypto.AesDecrypt(authorization.TargetName, key)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密姓名失败: %v", err)
	}
	idCard, err := crypto.AesDecrypt(authorization.TargetIdcard, key)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "解密身份证号失败: %v", err)
	}
	initFaceVerifyResp, err := l.svcCtx.CloudAuthService.InitFaceVerify(cloudauth.InitFaceVerifyParam{
		OuterOrderNo: outerOrderNo,
		CertName:     string(name),
		CertNo:       string(idCard),
		MetaInfo:     req.MetaInfo,
	})
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "初始化人脸认证失败: %v", err)
	}
	err = l.svcCtx.AuthorizationModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		authorization.AuthType = sql.NullInt64{
			Int64: req.AuthType,
			Valid: true,
		}
		authorization.GrantType = sql.NullString{
			String: model.AuthorizationGrantTypeFace,
			Valid:  true,
		}
		_, err = l.svcCtx.AuthorizationModel.Update(l.ctx, session, authorization)
		if err != nil {
			return err
		}
		authorizationFace := &model.AuthorizationFace{
			AuthorizationId:    authorization.Id,
			CertifyId:          initFaceVerifyResp.CertifyId,
			CertifyUrl:         initFaceVerifyResp.CertifyUrl,
			Status:             model.AuthorizationStatusPending,
			CertifyUrlExpireAt: time.Now().Add(time.Minute * 30),
			OuterOrderNo:       outerOrderNo,
		}
		_, err = l.svcCtx.AuthorizationFaceModel.Insert(l.ctx, session, authorizationFace)
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "更新授权信息失败: %v", err)
	}
	return &types.InitFaceVerifyResp{
		CertifyId:  initFaceVerifyResp.CertifyId,
		CertifyUrl: initFaceVerifyResp.CertifyUrl,
	}, nil
}
