package auth

import (
	"context"
	"fmt"
	"qnc-server/common/xerr"

	"github.com/bytedance/sonic"
	"github.com/pkg/errors"

	"qnc-server/app/main/api/internal/svc"
	"qnc-server/app/main/api/internal/types"
	"qnc-server/app/main/model"

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

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

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

func (l *GetFaceVerifyResultLogic) GetFaceVerifyResult(req *types.GetFaceVerifyResultReq) (resp *types.GetFaceVerifyResultResp, err error) {
	// 1. 查询认证明细
	face, err := l.svcCtx.AuthorizationFaceModel.FindOneByCertifyId(l.ctx, req.CertifyId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询认证明细失败: %v", err)
	}
	if face == nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询认证明细为空")
	}

	// 2. 查询主授权（如后续需要可用）
	auth, err := l.svcCtx.AuthorizationModel.FindOne(l.ctx, face.AuthorizationId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权主表失败: %v", err)
	}

	// 3. 判断人脸认证明细和主授权状态，若均已是"success"，则直接返回通过
	if (face.Status == model.AuthorizationFaceStatusSuccess) && (auth.Status == model.AuthorizationStatusSuccess) {
		return &types.GetFaceVerifyResultResp{
			OrderID: auth.OrderId,
			Passed:  true,
		}, nil
	}

	// 4. 调用阿里云接口查询认证结果
	describeResp, err := l.svcCtx.CloudAuthService.DescribeFaceVerify(req.CertifyId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "校验人脸识别结果失败: %v", err)
	}

	// 5. 判断认证状态并更新（使用事务）
	if describeResp.Passed {
		// 使用事务更新状态
		err = l.svcCtx.AuthorizationModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
			order, err := l.svcCtx.OrderModel.FindOne(ctx, auth.OrderId)
			if err != nil {
				return errors.Wrapf(err, "查询订单失败")
			}
			redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
			cache, cacheErr := l.svcCtx.Redis.GetCtx(ctx, redisKey)
			if cacheErr != nil {
				return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
			}
			var data types.QueryCacheLoad
			err = sonic.Unmarshal([]byte(cache), &data)
			if err != nil {
				return fmt.Errorf("解析缓存内容失败: %+v", err)
			}
			// 插入新queryModel
			query := &model.Query{
				OrderId:     auth.OrderId,
				UserId:      auth.UserId,
				ProductId:   order.ProductId,
				QueryParams: data.Params,
				QueryState:  "pending",
			}
			_, insertQueryErr := l.svcCtx.QueryModel.Insert(ctx, session, query)
			if insertQueryErr != nil {
				return errors.Wrapf(insertQueryErr, "保存查询失败")
			}
			// 更新主授权状态
			auth.Status = model.AuthorizationStatusSuccess
			_, err = l.svcCtx.AuthorizationModel.Update(ctx, session, auth)
			if err != nil {
				return errors.Wrapf(err, "更新授权状态失败")
			}
			// 更新人脸认证明细状态
			face.Status = model.AuthorizationFaceStatusSuccess
			_, err = l.svcCtx.AuthorizationFaceModel.Update(ctx, session, face)
			if err != nil {
				return errors.Wrapf(err, "更新人脸认证状态失败")
			}
			if asyncErr := l.svcCtx.AsynqService.SendQueryTask(auth.OrderId); asyncErr != nil {
				logx.Errorf("异步任务调度失败: %v", asyncErr)
				return asyncErr
			}
			return nil
		})
		if err != nil {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新认证状态失败: %v", err)
		}
	}
	// 6. 返回resp（resp.Passed := describeResp.Passed）和err（如有）
	resp = &types.GetFaceVerifyResultResp{
		OrderID:  auth.OrderId,
		Passed:   describeResp.Passed,
		AuthType: auth.AuthType.Int64,
	}
	return resp, nil
}
