package card_info_t_mall_game

import (
	"context"
	"encoding/json"
	"fmt"
	"kami/internal/consts"
	"kami/internal/errHandler"
	"kami/internal/model"
	"kami/internal/service"
	"kami/utility/cache"
	"kami/utility/integration/agiso"
	tmallAPI "kami/utility/integration/tmall/api"
	"kami/utility/pool"
	"strconv"

	"github.com/bytedance/sonic"
	"github.com/duke-git/lancet/v2/pointer"
	"github.com/duke-git/lancet/v2/retry"
	"github.com/duke-git/lancet/v2/slice"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/os/gmutex"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/text/gregex"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"

	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"

	v1 "kami/api/card_info_t_mall_game/v1"
)

var (
	MuLockSign = gmutex.Mutex{}
)

func (c *ControllerV1) TMallGameAgisoCallback(ctx context.Context, req *v1.TMallGameAgisoCallbackReq) (res *v1.TMallGameAgisoCallbackRes, err error) {
	//加速,同一时间只能处理一个订单
	cacheN := cache.NewCache()
	isParallel := false
	MuLockSign.LockFunc(func() {
		result, _ := cacheN.Get(ctx, cache.TMallGameOrderSign.Key(req.Sign))
		//	订单存在的情况
		if result != nil && !result.IsNil() {
			isParallel = true
			return
		}
		//设置缓存
		_ = cacheN.Set(ctx, cache.TMallGameOrderSign.Key(req.Sign), 1, gtime.S*10)
	})
	if isParallel {
		err = gerror.NewCode(gcode.CodeOperationFailed, "订单正在处理，请勿重复推送")
		return
	}
	//释放锁
	defer func(cacheN *cache.Cache, ctx context.Context, keys ...interface{}) {
		_, _ = cacheN.Remove(ctx, keys)
	}(cacheN, ctx, cache.TMallGameOrderSign.Key(req.Sign))
	if req.Sign != agiso.GenerateCallbackSign(ctx, req.Json, req.TimeStamp) {
		glog.Error(ctx, "阿奇索验证失败", "阿奇索返回", req.Sign, "软件生成", agiso.GenerateCallbackSign(ctx, req.Json, req.TimeStamp))
		return res, gerror.New("阿奇索验证失败")
	}
	switch req.Aopic {
	//买家付款
	case consts.CALLBACK_PAYMENT_SUCCESS:
		//err = handleCallBackPaymentWithJudgementSuccess(ctx, req.Json)
		_ = pool.New(pool.TMallAccountCallback, 20).Add(context.WithoutCancel(ctx), func(ctx context.Context) {
			err = handleCallBackPaymentWithoutJudgementSuccess(ctx, req.Json)
		})
	case consts.CALLBACK_PAYMENT_TRADE_SUCCESS:
		//err = handleBuyerConfirmWithJudgementMessage(ctx, req.Json)
		_ = pool.New(pool.TMallAccountCallback, 20).Add(context.WithoutCancel(ctx), func(ctx context.Context) {
			err = handleBuyerConfirmWithoutJudgementMessage(ctx, req.Json)
		})
	//买家申请退款
	case consts.Callback_PAYMENT_REFUND_APPLY:
		glog.Info(ctx, "买家申请退款", req.Json)
	case consts.CALLBACK_EVALUATION_SUCCESS:
		err = handleEvaluationSuccess(ctx, req.Json)
	default:
		glog.Error(ctx, "未知的回调类型", req.Aopic, req.Json)
	}
	return
}

// handleCallBackPaymentJudgementSuccess 处理发货
func handleCallBackPaymentWithJudgementSuccess(ctx context.Context, reqJson string) (err error) {
	tbTradeBuyerPay := agiso.TBTradeBuyerPay{}
	if err = json.Unmarshal([]byte(reqJson), &tbTradeBuyerPay); err != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, gerror.Wrap(err, fmt.Sprintf("返回数据：%s", reqJson)), "json解析失败：")
		return
	}
	rechargeTMallGameOrder := service.RechargeTMallGameOrder()
	//判断当前订单是否已经推送过
	if isExist, _ := rechargeTMallGameOrder.IsExist(ctx, gconv.String(tbTradeBuyerPay.Tid)); isExist {
		err = gerror.New("订单已经存在，重复推送")
		return
	}
	//写入基本shop订单
	shopId, err2 := rechargeTMallGameOrder.AddAgisoCallBackBaseInfo(ctx, &model.AddAgisoCallBackBaseInfoInput{
		TMallOrderId: tbTradeBuyerPay.Tid,
		BuyerNick:    tbTradeBuyerPay.BuyerNick,
		Status:       consts.RechargeTMallGameOrderStatusCallback,
		Payment:      tbTradeBuyerPay.Payment,
		OriginalData: reqJson,
	}, nil)
	if err2 != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err2, "添加阿奇索基本信息失败")
		return
	}
	//向淘宝获取订单信息，需要的信息在淘宝备注里
	tbTrade, err2 := tmallAPI.NewClient().TBMallTradeGet(ctx, tbTradeBuyerPay.Tid)
	if err2 != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err2, "淘宝订单信息获取失败")
		return
	}
	if err2 = rechargeTMallGameOrder.UpdateTMallCallBackInfo(ctx, &model.UpdateAgisoCallBackInfoInput{
		Id:           shopId,
		TMallOrderId: gconv.String(tbTrade.Tid),
		Created:      gconv.GTime(tbTrade.Created),
		BuyerNick:    gconv.String(tbTrade.BuyerNick),
		Status:       consts.EnumShopStatusPaidEnumShopStatus,
		BuyerRate:    gconv.Int(tbTrade.BuyerRate),
		TradeStatus:  gconv.String(tbTrade.Status),
		Payment:      gconv.String(tbTrade.Payment),
		TotalFee:     gconv.String(tbTrade.TotalFee),
		PayTime:      gconv.GTime(tbTrade.PayTime),
		BuyerMemo:    gconv.String(tbTrade.BuyerMemo),
		AlipayNo:     gconv.String(tbTrade.AlipayNo),
		BuyerMessage: gconv.String(tbTrade.BuyerMessage),
		OriginalData: string(gjson.MustEncode(tbTrade)),
		SourceType:   consts.RechargeTMallGameShopSourceTypeTMall,
	}, nil); err2 != nil {
		glog.Error(ctx, "更新阿奇索回调信息失败,返回数据", fmt.Sprintf("返回数据：%s", reqJson))
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err, "添加阿奇索细节信息失败")
		return
	}
	//获取关联订单，将shop订单关联到主订单中
	if err2 = rechargeTMallGameOrder.AssociateCreatedOrderAndStatus(ctx, &model.AssociateCreatedOrderAndStatusInput{
		AccountNumber: gconv.String(tbTrade.BuyerMessage),
		ShopId:        int(shopId),
	}, nil); err2 != nil {
		glog.Error(ctx, "主订单关联失败，返回数据", reqJson, "订单数据", tbTrade, "返回错误信息", err2)
		return
	}
	//查找对应订单
	orderInfo, err2 := rechargeTMallGameOrder.GetByShopId(ctx, shopId, nil)
	if err2 != nil {
		glog.Error(ctx, "管理订单数据失败", err2)
		return
	}
	if orderInfo.Amount != gconv.Float64(tbTradeBuyerPay.Payment) {
		// 金额不符
		if err4 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:    orderInfo.OrderNo,
			Status:     consts.RechargeTMallGameOrderStatusFinishedWithWrongAmount,
			SourceType: consts.RechargeTMallGameShopSourceTypeAgiso,
		}, nil); err4 != nil {
			glog.Error(ctx, "更新订单数据失败", err4)
		}
		return
	}
	tMallClient := tmallAPI.NewClient()
	glog.Info(ctx, "开始发货, 订单号：", orderInfo.OrderNo)
	//尝试发货，尝试三次
	err2 = retry.Retry(func() error {
		if isSucceed, err3 := tMallClient.VirtualDelivery(ctx, gconv.Int64(tbTrade.Tid)); !isSucceed || err3 != nil {
			err4 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
				OrderNo:    orderInfo.OrderNo,
				Status:     consts.RechargeTMallGameOrderStatusDeliveryFailed,
				SourceType: consts.RechargeTMallGameShopSourceTypeTMall,
			}, nil)
			if err4 != nil {
				glog.Error(ctx, "更新订单数据失败", err4)
			}
			return err3
		} else {
			glog.Info(ctx, "虚拟发货成功")
			if err4 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
				OrderNo:    orderInfo.OrderNo,
				Status:     consts.RechargeTMallGameOrderStatusDeliverySucceed,
				SourceType: consts.RechargeTMallGameShopSourceTypeTMall,
			}, nil); err4 != nil {
				if err4 != nil {
					glog.Error(ctx, "更新订单数据失败", err4)
				}
			}
		}
		return nil
	}, retry.RetryTimes(3), retry.Context(ctx))
	if err2 != nil {
		glog.Error(ctx, "虚拟发货失败", err2)
	}
	return
}

// handleBuyerConfirmWithJudgementMessage 买家确认收货
func handleBuyerConfirmWithJudgementMessage(ctx context.Context, reqJson string) (err error) {
	// OrderItem 代表订单中的商品信息
	type OrderItem struct {
		Oid                               int64  `json:"Oid"`
		OidStr                            string `json:"OidStr"`
		NumIid                            int64  `json:"NumIid"`
		OuterIid                          string
		OuterSkuId                        string
		Title                             string `json:"Title"`
		Price                             string `json:"Price"`
		Num                               int    `json:"Num"`
		TotalFee                          string `json:"TotalFee"`
		Payment                           string `json:"Payment"`
		PicPath                           string `json:"PicPath"`
		SkuId                             int64
		SkuPropertiesName                 string
		DivideOrderFee                    string `json:"DivideOrderFee"`
		PartMjzDiscount                   string
		ExpandCardExpandPriceUsedSuborder interface{} `json:"ExpandCardExpandPriceUsedSuborder"`
		Customization                     string
	}
	// Order 代表订单信息
	type Order struct {
		Platform                  string `json:"Platform"`
		PlatformUserId            string `json:"PlatformUserId"`
		ReceiverName              string
		ReceiverMobile            string
		ReceiverPhone             string
		ReceiverAddress           string `json:"ReceiverAddress"`
		BuyerArea                 string
		ExtendedFields            map[string]interface{} `json:"ExtendedFields"`
		Tid                       int64                  `json:"Tid"`
		TidStr                    string                 `json:"TidStr"`
		Status                    string                 `json:"Status"`
		SellerNick                string                 `json:"SellerNick"`
		BuyerNick                 string                 `json:"BuyerNick"`
		BuyerOpenUid              string                 `json:"BuyerOpenUid"`
		Type                      string                 `json:"Type"`
		BuyerMessage              string                 `json:"BuyerMessage"`
		Price                     string                 `json:"Price"`
		Num                       int                    `json:"Num"`
		TotalFee                  string                 `json:"TotalFee"`
		Payment                   string                 `json:"Payment"`
		PayTime                   string                 `json:"PayTime"`
		PicPath                   string                 `json:"PicPath"`
		PostFee                   string                 `json:"PostFee"`
		Created                   string                 `json:"Created"`
		TradeFrom                 string                 `json:"TradeFrom"`
		Orders                    []OrderItem            `json:"Orders"`
		SellerMemo                *string
		SellerFlag                int `json:"SellerFlag"`
		CreditCardFee             string
		ExpandCardExpandPriceUsed interface{} `json:"ExpandCardExpandPriceUsed"`
	}
	tbTradeConfirmMsg := Order{}
	if err = sonic.UnmarshalString(reqJson, &tbTradeConfirmMsg); err != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, gerror.Wrap(err, fmt.Sprintf("返回数据：%s", reqJson)), "json解析失败：")
		return
	}
	rechargeTMallGameOrder := service.RechargeTMallGameOrder()
	shopOrderInfo, err := rechargeTMallGameOrder.GetShopOneByTid(ctx, strconv.FormatInt(tbTradeConfirmMsg.Tid, 10), nil)
	if err != nil || shopOrderInfo.Id == 0 {
		glog.Error(ctx, "获取订单数据失败", err)
		return
	}
	//获取order订单
	orderInfo, err := rechargeTMallGameOrder.GetById(ctx, shopOrderInfo.OrderNo, nil)
	if err != nil || pointer.IsNil(orderInfo) || orderInfo.Id == 0 {
		glog.Error(ctx, "获取订单数据失败，账户可能没有关联订单", err)
		return
	}
	//判断是不是发货成功状态
	if orderInfo.Status != string(consts.RechargeTMallGameOrderStatusDeliverySucceed) {
		glog.Error(ctx, "订单状态不是发货成功状态，不能确认收货")
		return
	}
	if consts.RechargeTMallGameCallBackType(orderInfo.CallbackType) == consts.RechargeTMallGameCallBackTypeConfirm {
		if err3 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      shopOrderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusFinished,
			SourceType:   consts.RechargeTMallGameShopSourceTypeAgiso,
			OriginalData: reqJson,
		}, nil); err3 != nil {
			glog.Error(ctx, "更新订单数据失败", err)
			return err3
		}
		if consts.RechargeTMallGameCallBackType(orderInfo.CallbackType) == consts.RechargeTMallGameCallBackTypeConfirm {
			//	回调给第三方
			if err3 := rechargeTMallGameOrder.CallBackOrderToUpstream(ctx, orderInfo.OrderNo); err3 != nil {
				glog.Error(ctx, "回调第三方失败", err)
			}
		}
	} else {
		if err3 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      shopOrderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusWaitForEvaluation,
			SourceType:   consts.RechargeTMallGameShopSourceTypeAgiso,
			OriginalData: reqJson,
		}, nil); err3 != nil {
			glog.Error(ctx, "更新订单数据失败", err)
			return err3
		}
	}
	return
}

func handleEvaluationSuccess(ctx context.Context, reqJson string) (err error) {
	type evaluationModel struct {
		Tid          string `json:"Tid"`
		TidStr       string `json:"TidStr"`
		Oid          string `json:"Oid"`
		OidStr       string `json:"OidStr"`
		NumIid       int64  `json:"NumIid"`
		BuyerNick    string `json:"BuyerNick"`
		BuyerOpenUid string `json:"BuyerOpenUid"`
		Content      string `json:"Content"`
		Result       string `json:"Result"`
		ValidScore   bool   `json:"ValidScore"`
		Created      string `json:"Created"`
	}
	tbEvaluationList := make([]evaluationModel, 0)
	if err = json.Unmarshal([]byte(reqJson), &tbEvaluationList); err != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, gerror.Wrap(err, fmt.Sprintf("返回数据：%s", reqJson)), "json解析失败：")
		return
	}
	if tbEvaluationList == nil || len(tbEvaluationList) == 0 {
		return
	}
	isEvaluationGood := true
	for _, e := range tbEvaluationList {
		if e.Result != "good" {
			isEvaluationGood = false
			break
		}
	}
	orderService := service.RechargeTMallGameOrder()
	shopOrderInfo, err := orderService.GetShopOneByTid(ctx, tbEvaluationList[0].Tid, nil)
	if err != nil || shopOrderInfo.Id == 0 {
		glog.Error(ctx, "获取订单数据失败", err)
		return
	}
	orderInfo, err2 := orderService.GetByShopId(ctx, int64(shopOrderInfo.Id), nil)
	if err2 != nil {
		glog.Error(ctx, "读取内部存储订单数据错误", err2)
		return
	}
	if consts.RechargeTMallGameCallBackType(orderInfo.CallbackType) != consts.RechargeTMallGameCallBackTypeEvaluation {
		return
	}
	//判断是不是发货成功状态
	if orderInfo.Status != string(consts.RechargeTMallGameOrderStatusWaitForEvaluation) {
		glog.Error(ctx, "订单状态不是等待发货状态，不能评价")
		return
	}
	if isEvaluationGood {
		_ = orderService.UpdateShopOrderStatusById(ctx, int(shopOrderInfo.Id), consts.EnumShopStatusEvaluationGood, nil)
		//获取详细的评价数据
		_ = orderService.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      orderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderEvaluation,
			OriginalData: reqJson,
			SourceType:   consts.RechargeTMallGameShopSourceTypeTMall,
		}, nil)
		//给买家好评
		tMallClient := tmallAPI.NewClient()
		isSucceed, _ := tMallClient.TradeRatesAdd(ctx, gconv.Int64(shopOrderInfo.TMallOrderNo))
		if isSucceed {
			_ = orderService.UpdateShopOrderStatusById(ctx, int(shopOrderInfo.Id), consts.EnumShopStatusEvaluatedSucceed, nil)
			//_ = orderService.UpdateOrderStatusByShopOrderId(ctx, shopOrderInfo.Id, consts.EnumShopStatusEvaluatedSucceed, nil)
			_ = orderService.AddOrderHistory(ctx, &model.AddAgisoCallBackHistoryInput{
				OrderNo:    shopOrderInfo.OrderNo,
				Status:     consts.RechargeTMallGameOrderTradeRatesAddSucceed,
				SourceType: consts.RechargeTMallGameShopSourceTypeTMall,
			}, nil)
		} else {
			_ = orderService.UpdateShopOrderStatusById(ctx, int(shopOrderInfo.Id), consts.EnumShopStatusEvaluatedFailed, nil)
			_ = orderService.AddOrderHistory(ctx, &model.AddAgisoCallBackHistoryInput{
				OrderNo:    shopOrderInfo.OrderNo,
				Status:     consts.RechargeTMallGameOrderTradeRatesAddFailed,
				SourceType: consts.RechargeTMallGameShopSourceTypeTMall,
			}, nil)
		}
		if err3 := orderService.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:    shopOrderInfo.OrderNo,
			Status:     consts.RechargeTMallGameOrderStatusFinished,
			SourceType: consts.RechargeTMallGameShopSourceTypeTMall,
		}, nil); err3 != nil {
			glog.Error(ctx, "更新订单数据失败", err)
			return
		}
		//	回调给第三方
		if err3 := orderService.CallBackOrderToUpstream(ctx, shopOrderInfo.OrderNo); err3 != nil {
			glog.Error(ctx, "回调第三方失败", err)
			return
		}
	} else {
		_ = orderService.UpdateShopOrderStatusById(ctx, int(shopOrderInfo.Id), consts.EnumShopStatusEvaluationBad, nil)
		_ = orderService.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      shopOrderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusFinishedWithWrongStatus,
			OriginalData: reqJson,
			SourceType:   consts.RechargeTMallGameShopSourceTypeTMall,
		}, nil)
	}
	return
}

//// 处理买家退款情况
//func handlePaymentRefundApply(ctx context.Context, reqJson string) (err error) {
//	//	查询订单
//	orderService := service.RechargeTMallGameOrder()
//	shopOrder, err := orderService.GetShopOneByTid(ctx, "", nil)
//	if err != nil || shopOrder.Id == 0 {
//		glog.Info(ctx, "查询订单失败", err)
//	}
//	if shopOrder.Status != string(consts.RechargeTMallGameOrderStatusFinishedWithWrongAmount) {
//		_ = orderService.AddOrderHistory(ctx, &model.AddAgisoCallBackHistoryInput{
//			OrderNo:             shopOrder.OrderNo,
//			TMallOrderId:        int(shopOrder.TMallOrderNo),
//			RechargeTMallShopId: int64(shopOrder.Id),
//			OriginalData:        reqJson,
//			Status:              consts.RechargeTMallGameOrderStatusRefundFailed,
//			SourceType:          "",
//			Remark:              "退款失败，当前订单状态不是退款状态",
//		}, nil)
//		//	如果当前订单金额错误，就给对方退款
//		return
//	}
//	tMallClient := tmallAPI.NewClient()
//	//退款成功
//	_ = orderService.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
//		OrderNo:      shopOrder.OrderNo,
//		TMallOrderId: int(shopOrder.TMallOrderNo),
//		Status:       consts.RechargeTMallGameOrderStatusFinishedWithRefundSucceed,
//		OriginalData: reqJson,
//		SourceType:   consts.RechargeTMallGameShopSourceTypeTMall,
//	}, nil)
//}

// handleCallBackPaymentJudgementSuccess 处理发货
func handleCallBackPaymentWithoutJudgementSuccess(ctx context.Context, reqJson string) (err error) {
	tbTradeBuyerPay := agiso.TBTradeBuyerPay{}
	if err = json.Unmarshal([]byte(reqJson), &tbTradeBuyerPay); err != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, gerror.Wrap(err, fmt.Sprintf("返回数据：%s", reqJson)), "json解析失败：")
		return
	}
	rechargeTMallGameOrder := service.RechargeTMallGameOrder()
	//判断当前订单是否已经推送过
	if isExist, _ := rechargeTMallGameOrder.IsExist(ctx, gconv.String(tbTradeBuyerPay.Tid)); isExist {
		err = gerror.New("订单已经存在，重复推送")
		return
	}
	//写入淘宝订单信息
	shopId, err2 := rechargeTMallGameOrder.AddAgisoCallBackBaseInfo(ctx, &model.AddAgisoCallBackBaseInfoInput{
		TMallOrderId: tbTradeBuyerPay.Tid,
		BuyerNick:    tbTradeBuyerPay.BuyerNick,
		Status:       consts.RechargeTMallGameOrderStatusCallback,
		Payment:      tbTradeBuyerPay.Payment,
		OriginalData: reqJson,
	}, nil)
	if err2 != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err2, "添加阿奇索基本信息失败")
		return
	}
	//向淘宝获取订单详情
	tbTrade, err2 := tmallAPI.NewClient().TBMallTradeGet(ctx, tbTradeBuyerPay.Tid)
	if err2 != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err2, "淘宝订单信息获取失败")
		return
	}
	if err2 = rechargeTMallGameOrder.UpdateTMallCallBackInfo(ctx, &model.UpdateAgisoCallBackInfoInput{
		Id:           shopId,
		TMallOrderId: gconv.String(tbTradeBuyerPay.Tid),
		Created:      gconv.GTime(tbTrade.Created.String()),
		BuyerNick:    gconv.String(tbTrade.BuyerNick),
		Status:       consts.EnumShopStatusPaidEnumShopStatus,
		BuyerRate:    gconv.Int(tbTrade.BuyerRate),
		TradeStatus:  gconv.String(tbTrade.Status),
		Payment:      gconv.String(tbTrade.Payment),
		TotalFee:     gconv.String(tbTrade.TotalFee),
		PayTime:      gconv.GTime(tbTrade.PayTime),
		BuyerMemo:    gconv.String(tbTrade.BuyerMemo),
		AlipayNo:     gconv.String(tbTrade.AlipayNo),
		BuyerMessage: gconv.String(tbTrade.BuyerMessage),
		OriginalData: gconv.String(gjson.MustEncode(tbTrade)),
		SourceType:   consts.RechargeTMallGameShopSourceTypeTMall,
	}, nil); err2 != nil {
		glog.Error(ctx, "更新阿奇索回调信息失败,返回数据", fmt.Sprintf("返回数据：%s", reqJson))
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, err, "添加阿奇索细节信息失败")
		return
	}
	tMallClient := tmallAPI.NewClient()
	//尝试发货，尝试三次
	err2 = retry.Retry(func() error {
		if isSucceed, err3 := tMallClient.VirtualDelivery(ctx, gconv.Int64(tbTrade.Tid)); !isSucceed || err3 != nil {
			err4 := rechargeTMallGameOrder.AddShopHistory(ctx, &model.AddOrderShopHistoryInput{
				ShopId:  int(shopId),
				RawData: "",
				Remark:  "",
				Status:  consts.EnumShopStatusDeliveryFailed,
			}, nil)
			if err4 != nil {
				glog.Error(ctx, "更新订单数据失败", err4)
			}
			return err3
		} else {
			glog.Info(ctx, "虚拟发货成功")
			err4 := rechargeTMallGameOrder.AddShopHistory(ctx, &model.AddOrderShopHistoryInput{
				ShopId:  int(shopId),
				RawData: "",
				Remark:  "",
				Status:  consts.EnumShopStatusDeliverySucceed,
			}, nil)
			if err4 != nil {
				glog.Error(ctx, "更新订单数据失败", err4)
			}
		}
		return nil
	}, retry.Context(ctx))
	if err2 != nil {
		glog.Error(ctx, "虚拟发货失败", err2)
	}
	return
}

// handleBuyerConfirmWithoutJudgementMessage 买家确认收货
func handleBuyerConfirmWithoutJudgementMessage(ctx context.Context, reqJson string) (err error) {
	type OrderItem struct {
		Oid                               int64  `json:"Oid"`
		OidStr                            string `json:"OidStr"`
		NumIid                            int64  `json:"NumIid"`
		OuterIid                          string
		OuterSkuId                        string
		Title                             string `json:"Title"`
		Price                             string `json:"Price"`
		Num                               int    `json:"Num"`
		TotalFee                          string `json:"TotalFee"`
		Payment                           string `json:"Payment"`
		PicPath                           string `json:"PicPath"`
		SkuId                             int64
		SkuPropertiesName                 string
		DivideOrderFee                    string `json:"DivideOrderFee"`
		PartMjzDiscount                   string
		ExpandCardExpandPriceUsedSuborder interface{} `json:"ExpandCardExpandPriceUsedSuborder"`
		Customization                     string
	}
	// Order 代表订单信息
	type Order struct {
		Platform                  string `json:"Platform"`
		PlatformUserId            string `json:"PlatformUserId"`
		ReceiverName              string
		ReceiverMobile            string
		ReceiverPhone             string
		ReceiverAddress           string `json:"ReceiverAddress"`
		BuyerArea                 string
		ExtendedFields            map[string]interface{} `json:"ExtendedFields"`
		Tid                       int64                  `json:"Tid"`
		TidStr                    string                 `json:"TidStr"`
		Status                    string                 `json:"Status"`
		SellerNick                string                 `json:"SellerNick"`
		BuyerNick                 string                 `json:"BuyerNick"`
		BuyerOpenUid              string                 `json:"BuyerOpenUid"`
		Type                      string                 `json:"Type"`
		BuyerMessage              string                 `json:"BuyerMessage"`
		Price                     string                 `json:"Price"`
		Num                       int                    `json:"Num"`
		TotalFee                  string                 `json:"TotalFee"`
		Payment                   string                 `json:"Payment"`
		PayTime                   string                 `json:"PayTime"`
		PicPath                   string                 `json:"PicPath"`
		PostFee                   string                 `json:"PostFee"`
		Created                   string                 `json:"Created"`
		TradeFrom                 string                 `json:"TradeFrom"`
		Orders                    []OrderItem            `json:"Orders"`
		SellerMemo                *string
		SellerFlag                int `json:"SellerFlag"`
		CreditCardFee             string
		ExpandCardExpandPriceUsed interface{} `json:"ExpandCardExpandPriceUsed"`
	}
	tbTradeConfirmMsg := Order{}
	if err = sonic.UnmarshalString(reqJson, &tbTradeConfirmMsg); err != nil {
		err = errHandler.WrapError(ctx, gcode.CodeInternalError, gerror.Wrap(err, fmt.Sprintf("json解析失败：返回数据：%s", reqJson)))
		return
	}
	rechargeTMallGameOrder := service.RechargeTMallGameOrder()
	shopOrderInfo, err := rechargeTMallGameOrder.GetShopOneByTid(ctx, strconv.FormatInt(tbTradeConfirmMsg.Tid, 10), nil)
	if err != nil || shopOrderInfo.Id == 0 {
		glog.Error(ctx, "获取已有淘宝订单失败", err)
		return
	}
	rechargeTMallGameOrder.UpdateEndTime(ctx, gconv.Int64(shopOrderInfo.Id))
	accountList, err := gregex.MatchString(`游戏账号:(.*)`, tbTradeConfirmMsg.ReceiverAddress)
	if len(accountList) != 2 {
		_ = rechargeTMallGameOrder.UpdateShopOrderStatusById(ctx, int(shopOrderInfo.Id), consts.EnumShopStatusBindOrderFail, nil)
		_ = rechargeTMallGameOrder.AddShopHistory(ctx, &model.AddOrderShopHistoryInput{
			ShopId:  int(shopOrderInfo.Id),
			RawData: reqJson,
			Remark:  tbTradeConfirmMsg.ReceiverAddress,
			Status:  consts.EnumShopStatusBindOrderFail,
		}, nil)
		return
	}
	//获取关联订单，将shop订单关联到主订单中
	slice.ForEach(accountList, func(index int, item string) {
		accountList[index] = gstr.TrimAll(item)
	})
	//关联天猫订单和自身订单
	if err2 := rechargeTMallGameOrder.AssociateCreatedOrderAndStatus(ctx, &model.AssociateCreatedOrderAndStatusInput{
		AccountNumber: accountList[1],
		ShopId:        int(shopOrderInfo.Id),
	}, nil); err2 != nil {
		glog.Error(ctx, fmt.Sprintf("主订单关联失败，返回数据：%s\n%v", reqJson, shopOrderInfo), err2)
		return
	}
	//获取关联的自身订单号
	orderInfo, err := rechargeTMallGameOrder.GetByShopId(ctx, gconv.Int64(shopOrderInfo.Id), nil)
	if err != nil || pointer.IsNil(orderInfo) || orderInfo.Id == 0 {
		glog.Error(ctx, "获取订单数据失败，账户可能没有关联订单", err)
		return
	}
	//判断是不是发货成功状态
	//if orderInfo.Status != string(consts.RechargeTMallGameOrderStatusPaid) {
	//	glog.Error(ctx, "订单状态不是发货成功状态，不能确认回调")
	//	return
	//}
	if orderInfo.Amount != gconv.Float64(shopOrderInfo.Payment) {
		// 金额不符
		if err4 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      orderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusFinishedWithWrongAmount,
			SourceType:   consts.RechargeTMallGameShopSourceTypeAgiso,
			OriginalData: reqJson,
		}, nil); err4 != nil {
			glog.Error(ctx, "更新订单数据失败", err4)
		}
		return
	}
	if consts.RechargeTMallGameCallBackType(orderInfo.CallbackType) == consts.RechargeTMallGameCallBackTypeConfirm {
		if err3 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      orderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusFinished,
			SourceType:   consts.RechargeTMallGameShopSourceTypeAgiso,
			OriginalData: reqJson,
		}, nil); err3 != nil {
			glog.Error(ctx, "更新订单数据失败", err)
			return err3
		}
		if consts.RechargeTMallGameCallBackType(orderInfo.CallbackType) == consts.RechargeTMallGameCallBackTypeConfirm {
			//	回调给第三方
			if err3 := rechargeTMallGameOrder.CallBackOrderToUpstream(ctx, orderInfo.OrderNo); err3 != nil {
				glog.Error(ctx, "回调第三方失败", err)
			}
		}
	} else {
		if err3 := rechargeTMallGameOrder.UpdateOrderStatusByTBOrderNo(ctx, &model.UpdateOrderStatusByTBOrderNoInput{
			OrderNo:      orderInfo.OrderNo,
			Status:       consts.RechargeTMallGameOrderStatusWaitForEvaluation,
			SourceType:   consts.RechargeTMallGameShopSourceTypeAgiso,
			OriginalData: reqJson,
		}, nil); err3 != nil {
			glog.Error(ctx, "更新订单数据失败", err)
			return err3
		}
	}
	return
}
