package localjx

import (
	"encoding/json"
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
	"git.rosy.net.cn/baseapi/platformapi/weixinapi"
	"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
	"git.rosy.net.cn/jx-callback/business/partner"
	"strings"
	"time"

	"git.rosy.net.cn/jx-callback/globals"

	"git.rosy.net.cn/baseapi/platformapi/tonglianpayapi"
	"git.rosy.net.cn/baseapi/utils"

	"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/globals/api"
)

func pay4OrderByTL(ctx *jxcontext.Context, order *model.GoodsOrder, payType int, vendorPayType, subAppID, code string) (orderPay *model.OrderPay, err error) {
	// if order.FromStoreID != 0 {
	// 	result, _ := orderman.GetMatterStoreOrderCount(nil, order.FromStoreID)
	// 	if !result.Flag {
	// 		return nil, fmt.Errorf("该门店[%v]已在一周内申请过物料，请勿重复申请！", order.FromStoreID)
	// 	}
	// }
	payCreatedAt := time.Now()
	param := &tonglianpayapi.CreateUnitorderOrderParam{
		Trxamt:    int(order.ActualPayPrice),
		NotifyUrl: globals.TLPayNotifyURL,
		Reqsn:     order.VendorOrderID,
		PayType:   vendorPayType,
		//SubAppID:  subAppID,
	}
	//暂时做兼容处理
	if vendorPayType == "JSAPI" {
		param.PayType = tonglianpayapi.PayTypeWxXcx
	}
	if vendorPayType == tonglianpayapi.PayTypeWxXcx {
		param.SubAppID = subAppID
		authInfo, err := ctx.GetV2AuthInfo()
		// 微信小程序支付
		if err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini && authInfo.GetAuthTypeID() == subAppID {
			param.Acct = authInfo.GetAuthID()
		}
		if code != "" {
			appAuth := strings.Split(code, "_")
			sessionInfo, err := weixin.GetAPI(appAuth[0]).SNSCode2Session(appAuth[1])
			if err != nil {
				return nil, err
			}
			param.Acct = sessionInfo.OpenID
		}
	}
	if vendorPayType == tonglianpayapi.PayTypeZfbJS || vendorPayType == tonglianpayapi.PayTypeZfbApp {
		if authInfo, err := ctx.GetV2AuthInfo(); err == nil {
			param.Acct = authInfo.GetAuthID()
		}
		if param.Acct == "" {
			return nil, fmt.Errorf("未找到用户的认证ID！")
		}
	}
	if vendorPayType == tonglianpayapi.PayTypeH5 {
		param2 := &tonglianpayapi.CreateH5UnitorderOrderParam{
			Trxamt:    int(order.ActualPayPrice),
			NotifyUrl: globals.TLPayNotifyURL,
			Body:      "京西菜市",
			Charset:   "UTF-8",
		}
		err = api.TLpayAPI.CreateH5UnitorderOrder(param2)
	} else {
		result, err := api.TLpayAPI.CreateUnitorderOrder(param)
		if err == nil {
			var result2 tonglianpayapi.PayInfo
			json.Unmarshal([]byte(result.PayInfo), &result2)
			prePayID := result2.Package[strings.LastIndex(result2.Package, "=")+1 : len(result2.Package)]
			orderPay = &model.OrderPay{
				PayOrderID:    param.Reqsn,
				PayType:       payType,
				VendorPayType: vendorPayType,
				TransactionID: result.TrxID,
				VendorOrderID: order.VendorOrderID,
				VendorID:      order.VendorID,
				Status:        0,
				PayCreatedAt:  payCreatedAt,
				PrepayID:      prePayID,
				CodeURL:       utils.LimitUTF8StringLen(result.PayInfo, 3200),
				TotalFee:      int(order.ActualPayPrice),
			}
		}
	}
	return orderPay, err
}

// https://prodoc.allinpay.com/doc/1091/ 新增消息
func OnTLPayCallback(call *tonglianpayapi.CallBackResult) (err error) {
	switch call.TrxCode {
	case tonglianpayapi.MsgTypePay, "VSP681", "VSP683":
		err = onTLpayFinished(call)
	case tonglianpayapi.MsgTypeRefund, "VSP682", "VSP684":
		err = onTLpayRefund(call)
	case tonglianpayapi.MsgTypePayZFB:
		err = onTLpayFinished(call)
	case tonglianpayapi.MsgTypeRefundZFB:
		err = onTLpayRefund(call)
	default:

	}
	return err
}

func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) {
	orderPay := &model.OrderPay{
		PayOrderID: call.CusorderID,
		// PayType:    model.PayTypeTL,
	}
	orderPay.DeletedAt = utils.DefaultTimeValue
	db := dao.GetDB()
	if err = dao.GetEntity(db, orderPay, "PayOrderID", "DeletedAt"); err == nil {
		if orderPay.Status != 0 {
			return err
		}
		loc, _ := time.LoadLocation("Local")
		t1, _ := time.ParseInLocation("20060102150405", call.PayTime, loc)
		orderPay.PayFinishedAt = utils.Time2Pointer(t1)
		// orderPay.TransactionID = call.ChnlTrxID
		orderPay.OriginalData = utils.Format4Output(call, true)
		if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
			orderPay.Status = model.PayStatusYes
		} else {
			orderPay.Status = model.PayStatusFailed
		}
		dao.UpdateEntity(db, orderPay)
		if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
			err = OnPayFinished(orderPay)
			order, _ := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, model.VendorIDJX)
			if order != nil {
				store, _ := dao.GetStoreDetail(db, order.FromStoreID, model.VendorIDJX, "")
				if store != nil {
					//userID := make([]string, 0, 2)
					for _, v := range []string{store.MarketManPhone, store.OperatorPhone2} {
						if v == "" {
							continue
						}
						user, _ := dao.GetUserByID(db, "mobile", v)
						ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "商户购买物料信息推送", fmt.Sprintf("门店%s:%d,在物料商城下单了:%s,请注意查看", store.Name, store.ID, order.VendorOrderID))
						//userID = append(userID, user.UserID)
						//if store.MarketManPhone == store.OperatorPhone2 {
						//	break
						//}
					}
					//weixinmsg.SendUserMessage(jxcontext.AdminCtx, "商户购买物料信息推送", fmt.Sprintf("门店%s:%d,在物料商城下单了:%s,请注意查看", store.Name, store.ID, order.VendorOrderID), userID, true, true)
				}
				authList, _ := dao.GetUserBindAuthInfo(db, order.UserID, 0, nil, "", "", []string{api.WeixinMiniAppID2})
				if authList != nil && len(authList) != 0 {
					param := &weixinapi.SNSSendOrderParameter{
						OrderKey: struct {
							OrderNumberType int    `json:"order_number_type"`
							TransactionId   string `json:"transaction_id"`
							Mchid           string `json:"mchid"`
							OutTradeNo      string `json:"out_trade_no"`
						}{
							OrderNumberType: 2,
							TransactionId:   call.ChnlTrxID,
						},
						LogisticsType:  1,
						DeliveryMode:   1,
						IsAllDelivered: false,
						ShippingList: append([]weixinapi.ShippingList{}, weixinapi.ShippingList{
							TrackingNo:     order.VendorOrderID,
							ExpressCompany: "YD",
							ItemDesc:       "背心袋",
							Contact: struct {
								ConsignorContact string `json:"consignor_contact"`
								ReceiverContact  string `json:"receiver_contact"`
							}{},
						}),
						UploadTime: time.Now().Format(time.RFC3339),
						Payer: struct {
							Openid string `json:"openid"`
						}{
							Openid: authList[0].AuthID,
						},
					}
					jxutils.CallMsgHandlerAsync(func() {
						select {
						case <-time.After(5 * time.Second):
							if err = api.WeixinMiniAPI2.SNSSendGoodsOrder(param); err != nil {
								ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "物料发货推送", fmt.Sprintf("物料商城下单,发货错误:%s,请注意查看,err:%s,%s", order.VendorOrderID, err.Error(), utils.Format4Output(param, false)))
							}
						}
					}, call.ChnlTrxID)
				}

			}
		}
	} else {
		globals.SugarLogger.Debugf("onTLpayFinished msg:%s, err:%v", utils.Format4Output(call, true), err)
	}
	return err
}

func onTLpayRefund(call *tonglianpayapi.CallBackResult) (err error) {
	orderPayRefund := &model.OrderPayRefund{
		RefundID: call.CusorderID,
	}
	db := dao.GetDB()
	if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
		if call.TrxStatus == tonglianpayapi.TrxStatusSuccess {
			orderPayRefund.Status = model.RefundStatusYes
		} else {
			orderPayRefund.Status = model.RefundStatusFailed
		}
		orderPayRefund.OriginalData = utils.Format4Output(call, true)
		dao.UpdateEntity(db, orderPayRefund)
	} else if dao.IsNoRowsError(err) {
		globals.SugarLogger.Warnf("收到异常的退款事件, call:%s", utils.Format4Output(call, true))
	}

	orderPay := &model.OrderPay{
		VendorOrderID: orderPayRefund.VendorOrderID,
		VendorID:      jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID),
		PayType:       model.PayTypeWX,
		Status:        model.PayStatusYes,
	}
	orderPay.DeletedAt = utils.DefaultTimeValue
	if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil {
		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay)
	}
	return err
}

func RefundOrderByTL(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
	result, err := api.TLpayAPI.PayRefund(&tonglianpayapi.PayRefundParam{
		Trxamt:   refundFee,
		Reqsn:    utils.GetUUID(),
		Remark:   refundDesc,
		OldTrxID: orderPay.TransactionID,
	})
	if err == nil {
		orderPayRefund = &model.OrderPayRefund{
			RefundID:        refundID,
			VendorRefundID:  result.TrxID,
			VendorOrderID:   orderPay.VendorOrderID,
			VendorID:        orderPay.VendorID,
			Status:          model.RefundStatusNo,
			TransactionID:   orderPay.TransactionID,
			RefundFee:       refundFee,
			RefundCreatedAt: time.Now(),
		}
		dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
		db := dao.GetDB()
		if result.TrxStatus == tonglianpayapi.TrxStatusSuccess {
			orderPayRefund.Status = model.RefundStatusYes
		} else {
			orderPayRefund.Status = model.RefundStatusFailed
		}
		orderPayRefund.OriginalData = utils.Format4Output(result, true)
		dao.CreateEntity(db, orderPayRefund)

		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay)

		order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID)
		if err != nil {
			return nil, err
		}
		if order.TotalShopMoney == int64(refundFee) {
			order.Status = model.OrderStatusCanceled
			order.VendorStatus = "laKaLaRefund"
			dao.UpdateEntity(db, order, "Status", "VendorStatus")
		}
	}
	return orderPayRefund, err
}
