package sfps

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	beego "github.com/astaxie/beego/server/web"

	tao "git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
	"git.rosy.net.cn/jx-callback/business/partner/purchase/tao_vegetable"

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

	"git.rosy.net.cn/jx-callback/business/partner/delivery"

	"git.rosy.net.cn/jx-callback/business/jxutils"

	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/globals/api"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/partner"

	"git.rosy.net.cn/baseapi/platformapi/sfps2"
	"git.rosy.net.cn/jx-callback/business/model"
)

type DeliveryHandler struct {
}

var (
	curDeliveryHandler *DeliveryHandler
)

func init() {
	if api.SfPsAPI != nil {
		curDeliveryHandler = new(DeliveryHandler)
		partner.RegisterDeliveryPlatform(curDeliveryHandler, true)
	}
}

func (d DeliveryHandler) GetVendorID() int {
	return model.VendorIDSFPS
}

func (d DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) {
	return "", 0, fmt.Errorf("顺丰派送暂不支持此操作")
}

func (d DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) {
	store, err := dao.GetStoreDetail(dao.GetDB(), utils.Str2Int(vendorStoreID), model.VendorIDSFPS, "")
	if err == nil {
		storeDetail = &dao.StoreDetail2{
			Store: model.Store{
				Name:    store.Name,
				Tel1:    store.Tel1,
				Address: store.Address,
				Lat:     store.Lat,
				Lng:     store.Lng,
			},
			VendorID:      model.VendorIDSFPS,
			VendorStoreID: utils.Int2Str(storeID),
			CourierStatus: model.StoreStatusOpened,
		}
	}
	return storeDetail, err
}

func (d DeliveryHandler) IsErrStoreNotExist(err error) bool {
	return false
}

func (d DeliveryHandler) IsErrStoreExist(err error) bool {
	return false
}

func (d DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
	vendorOrgCode, err := dao.GetVendorOrgCode(dao.GetDB(), model.VendorIDSFPS, "", model.VendorOrgTypeDelivery)
	if err != nil {
		return nil, err
	}
	if len(vendorOrgCode) > 0 && vendorOrgCode[0].IsOpen == model.YES {
		return nil, fmt.Errorf("此平台配送已被系统关闭，暂不发配送 [%v]", vendorOrgCode[0].Comment)
	}

	if maxDeliveryFee == model.NO {
		if order.EarningType != model.EarningTypePoints {
			fee, err := d.GetWaybillFee(order)
			if err != nil {
				return nil, err
			}
			if fee.DeliveryFee >= model.DefMaxDeliveryFee {
				return nil, fmt.Errorf("顺丰超最高限价, 所需运费:%s, 最高限价:%s", jxutils.IntPrice2StandardCurrencyString(fee.DeliveryFee), jxutils.IntPrice2StandardCurrencyString(model.DefMaxDeliveryFee))
			}
		}
	}

	store, err := dao.GetStoreDetail(dao.GetDB(), getReallyStoreID(order.StoreID, order.JxStoreID), 0, "")
	if err != nil {
		return nil, err
	}

	var (
		weight        int
		flag          = false
		productDetail []*sfps2.ProductDetail
		param         = &sfps2.CreateOrderReq{}
	)
	if order.Weight >= 49500 || order.Weight <= model.NO {
		weight = 49500
	} else {
		weight = order.Weight
	}
	param = &sfps2.CreateOrderReq{
		//ShopId:          sfps2.SFShopStoreID,
		ShopOrderId:     order.VendorOrderID,
		OrderSource:     GetVendorSource(order.VendorID),
		OrderTime:       order.CreatedAt.Unix(),
		ShopType:        sfps2.OrderTypeSF,
		LbsType:         sfps2.LbsTypeGD,
		RiderPickMethod: sfps2.RiderPickUpMethodSTU,
		Receive: &sfps2.ReceiveAddress{
			UserName:    order.ConsigneeName,
			UserPhone:   order.ConsigneeMobile,
			UserAddress: order.ConsigneeAddress,
			UserLat:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)),
			UserLng:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)),
		},
		Shop: &sfps2.SfShopInfo{
			ShopName:    order.StoreName,
			ShopPhone:   store.Tel1,
			ShopAddress: store.Address,
			ShopLat:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)),
			ShopLng:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)),
		},
		OrderDetail: &sfps2.OrderDetail{
			TotalPrice:     order.ActualPayPrice,
			ProductType:    sfps2.ProductTypeFresh,
			WeightGram:     int64(weight),
			ProductNum:     int64(order.GoodsCount),
			ProductTypeNum: int64(order.SkuCount),
		},
	}
	// 城市维度获取顺丰门店id
	if len(store.CityName) > 0 {
		for k, v := range sfps2.SFCityStoreIDs {
			//globals.SugarLogger.Debugf("sfps GetWaybillFee store.CityName==%s,k=%s", store.CityName, k)
			if strings.Contains(store.CityName, k) || store.CityName == k {
				param.ShopId = v
				flag = true
			}
		}
	}
	if flag == false || len(store.CityName) == 0 {
		//flag = true //todo sf测试用
		return nil, errors.New("此城市暂时不在，顺丰配送业务范围")
	}
	if len(order.Skus) != model.NO {
		for _, v := range order.Skus {
			productDetail = append(productDetail, &sfps2.ProductDetail{
				ProductName: v.SkuName,
				ProductNum:  int64(v.Count),
			})
		}
	} else {
		productDetail = append(productDetail, &sfps2.ProductDetail{
			ProductName: "本地暂无商品储存信息",
			ProductNum:  int64(model.YES),
		})
	}
	param.OrderDetail.ProductDetail = productDetail

	sfOrderID, sfBillID, sfTotalPrice, sfReallyPrice, err := api.SfPsAPI.CreateOrder(param)
	if err != nil {
		return nil, err
	}

	// 系统加价
	desiredFee := utils.Float64TwoInt(sfTotalPrice) + utils.WayBillDeliveryMarkUp
	// 运营加价
	desiredFee += store.FreightMarkup
	bill = &model.Waybill{
		VendorOrderID:    order.VendorOrderID,
		OrderVendorID:    order.VendorID,
		VendorWaybillID:  sfOrderID,
		VendorWaybillID2: sfBillID,
		WaybillVendorID:  model.VendorIDSFPS,
		DesiredFee:       int64(desiredFee),
		ActualFee:        utils.Float64TwoInt64(sfReallyPrice),
	}
	delivery.OnWaybillCreated(bill)
	//todo 模拟新运单回调
	if _, err = partner.CurOrderManager.LoadWaybill(sfOrderID, model.VendorIDSFPS); fmt.Sprintf("%s", err) == "找不到相应运单" {
		//忽略找不到运单错误
		err = nil
		resp := OnWaybillMsg(sfps2.UrlIndexRiderStatus, sfps2.RiderStatus{
			ShopId:        utils.Str2Float64(sfps2.SFShopStoreID),
			SFOrderID:     sfOrderID,
			ShopOrderID:   order.VendorOrderID,
			UrlIndex:      sfps2.UrlIndexRiderStatus,
			OperatorName:  "",
			OperatorPhone: "",
			RiderLng:      0,
			RiderLat:      0,
			OrderStatus:   sfps2.OrderStatusNewOrder,
			StatusDesc:    sfps2.OrderStatusNewOrderDesc,
			SFUCode:       "",
			PushTime:      int(time.Now().Unix()),
		})
		if resp.ErrorCode != sfps2.SuccessCode {
			err = fmt.Errorf("%v,%s", err, resp.ErrorMsg)
		}
	}
	return bill, err
}

func (d DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
	money := int64(0)
	deductionFee, err := api.SfPsAPI.PreCancelOrder(bill.VendorWaybillID)
	if deductionFee == 0 || err != nil {
		money = 0
	} else {
		money = utils.Float64TwoInt64(deductionFee)
	}
	globals.SugarLogger.Debugf("CancelWaybill money=%d", money)
	if err = api.SfPsAPI.CancelOrder(bill.VendorWaybillID); err != nil {
		return err
	}
	bill.Status = model.WaybillStatusCanceled
	bill.Remark = cancelReason
	bill.DesiredFee = money //取消成功才赋值违约金
	bill.ActualFee = money
	globals.SugarLogger.Debugf("CancelWaybill bill=%s", utils.Format4Output(bill, false))

	partner.CurOrderManager.OnWaybillStatusChanged(bill)
	return nil
}

func (d DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
	var (
		weight int
		flag   = false
		//param  = &sfps2.PreCreateOrderReq{}
	)

	// 默认重量
	if order.Weight >= 49500 || order.Weight <= 0 {
		weight = 49500
	} else {
		weight = order.Weight
	}

	store, err := dao.GetStoreDetail(dao.GetDB(), getReallyStoreID(order.StoreID, order.JxStoreID), 0, "")
	if err != nil {
		return nil, err
	}
	param := &sfps2.PreCreateOrderReq{
		//ShopId:          sfps2.SFShopStoreID,
		UserLng:         utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)),
		UserLat:         utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)),
		UserAddress:     order.ConsigneeAddress,
		Weight:          int64(weight),
		ProductType:     sfps2.ProductTypeFresh,
		ShopType:        sfps2.OrderTypeSF,
		LbsType:         sfps2.LbsTypeGD,
		RiderPickMethod: sfps2.RiderPickUpMethodSTU,
		Shop: &sfps2.SfShopInfo{
			ShopName:    order.StoreName,
			ShopPhone:   store.Tel1,
			ShopAddress: store.Address,
			ShopLat:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)),
			ShopLng:     utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)),
		},
	}
	// 城市维度获取顺丰门店id
	if len(store.CityName) > 0 {
		for k, v := range sfps2.SFCityStoreIDs {
			//globals.SugarLogger.Debugf("sfps GetWaybillFee store.CityName==%s,k=%s", store.CityName, k)
			if strings.Contains(store.CityName, k) || store.CityName == k {
				param.ShopId = v
				flag = true
			}
		}
	}
	if flag == false || len(store.CityName) == 0 {
		//flag = true //todo sf测试用
		return nil, errors.New("此城市暂时不在，顺丰配送业务范围")
	}
	deliveryFeeInfo = &partner.WaybillFeeInfo{}
	price, err := api.SfPsAPI.PreCreateOrder(param)
	deliveryFeeInfo.DeliveryFee = utils.Float64TwoInt64(price)
	deliveryFeeInfo.RefAddFee = utils.Float64TwoInt64(price)
	return deliveryFeeInfo, err
}

func (d DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
	return fmt.Errorf("顺丰暂未实现投诉")
}

// GetDeliverLiquidatedDamages 获取取消运单违约金
func (d DeliveryHandler) GetDeliverLiquidatedDamages(orderId string, deliverId string) (money int64, err error) {
	waybill, err := dao.GetWaybills(dao.GetDB(), orderId, []int64{model.VendorIDSFPS})
	if len(waybill) == 0 || err != nil {
		return 0, err
	}
	deductionFee, err := api.SfPsAPI.PreCancelOrder(waybill[0].VendorWaybillID)
	if deductionFee == 0 || err != nil {
		return 0, err
	}
	money = utils.Float64TwoInt64(deductionFee)
	return money, nil
}

func (d DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *utils.RiderInfo, err error) {
	order, err := dao.GetWaybills(dao.GetDB(), orderId, []int64{model.VendorIDSFPS})
	if len(order) == 0 || err != nil {
		return nil, errors.New("顺丰 订单id无效，请检查")
	}
	//获取顺丰运单详情
	sfOrder, err := api.SfPsAPI.GetOrderStatus(order[0].VendorWaybillID)
	//获取顺丰骑手实时位置
	sfRider, err := api.SfPsAPI.GetRiderLatestPosition(sfOrder.OrderID)
	if sfRider == nil {
		return nil, errors.New("顺丰派送暂无骑手信息")
	}
	result := &utils.RiderInfo{
		OrderId:               orderId,
		ThirdCarrierOrderId:   sfOrder.OrderID,
		CourierName:           sfOrder.RiderName,
		CourierPhone:          sfOrder.RiderPhone,
		LogisticsProviderCode: utils.SFPSCode,
		LogisticsStatus:       utils.Float64TwoInt(sfOrder.OrderStatus), // 默认正在配送中
		Latitude:              sfRider.RiderLat,
		Longitude:             sfRider.RiderLng,
	}

	switch sfOrder.OrderStatus {
	case sfps2.OrderStatusNewOrder:
		result.LogisticsStatus = model.WaybillStatusNew
		result.LogisticsContext = model.RiderWaitRider
	case sfps2.OrderStatusTakeOrder:
		result.LogisticsStatus = model.WaybillStatusCourierAssigned
		result.LogisticsContext = model.RiderGetOrder
	case sfps2.OrderStatusArrivedStore:
		result.LogisticsStatus = model.WaybillStatusCourierArrived
		result.LogisticsContext = model.RiderToStore
	case sfps2.OrderStatusRiderArriving:
		result.LogisticsStatus = model.WaybillStatusDelivering
		result.LogisticsContext = model.RiderGetOrderDelivering
	case sfps2.OrderStatusFinished:
		result.LogisticsStatus = model.WaybillStatusDelivered
		result.LogisticsContext = model.RiderGetOrderDelivered
	case sfps2.OrderStatusOrderCancel:
		result.LogisticsStatus = model.WaybillStatusCanceled
		result.LogisticsContext = model.RiderGetOrderCanceled
	case sfps2.OrderStatusError:
		result.LogisticsStatus = model.WaybillStatusDeliverFailed
		result.LogisticsContext = model.RiderGetOrderDeliverFailed
	default:
		result.LogisticsStatus = 0
		result.LogisticsContext = model.RiderGetOrderDeliverOther
	}
	return result, nil
}

func (c *DeliveryHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
	return api.SfPsAPI.QueryTipFee(vendorWaybillID)
}

func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) {
	if rider, err := api.SfPsAPI.GetRiderLatestPosition(vendorWaybillID); err == nil && len(rider.RiderLng) > 0 && len(rider.RiderLat) > 0 {
		lng = utils.Str2Float64(rider.RiderLng)
		lat = utils.Str2Float64(rider.RiderLat)
		return lng, lat, nil
	}
	return 0, 0, err
}

func (c *DeliveryHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
	return api.SfPsAPI.AddTipFee(vendorWaybillID, tipFee)
}

// OnWaybillMsg 配送状态更改回调
func OnWaybillMsg(urlIndex string, msg interface{}) (resp *sfps2.CallbackResponse) {

	order, goodsOrder := GetWaybillByStatus(urlIndex, msg)
	//判断是否是果园
	if goodsOrder == nil && beego.BConfig.RunMode == model.ServerTypeVegetable {
		pushCallbackToGy(urlIndex, msg, model.ServerTypeFruits)
		return sfps2.SuccessResponse
	}
	if goodsOrder == nil && beego.BConfig.RunMode == model.ServerTypeFruits {
		pushCallbackToGy(urlIndex, msg, model.ServerTypePet)
		return sfps2.SuccessResponse
	}
	//多次取消回调只取第一次
	tempStatus := utils.Str2Int(order.VendorStatus)
	if tempStatus == sfps2.OrderStatusOrderCancel || tempStatus == sfps2.OrderStatusRiderCancel {
		bill, err := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, model.VendorIDSFPS)
		if err != nil {
			return sfps2.Err2CallbackResponse(err)
		}
		if bill.Status == model.OrderStatusCanceled {
			return sfps2.Err2CallbackResponse(nil)
		}
	}
	//获取实时订单信息

	sfOrder, err := api.SfPsAPI.GetOrderStatus(order.VendorWaybillID)
	if err != nil {
		return sfps2.Err2CallbackResponse(err)
	}
	if order.CourierMobile == "" {
		order.CourierName = sfOrder.RiderName
	}
	if order.CourierName == "" {
		order.CourierMobile = sfOrder.RiderPhone
	}

	sfTotalPrice := utils.Float64TwoInt(sfOrder.TotalPrice)
	sfActualPrice := utils.Float64TwoInt64(sfOrder.RealPayMoney)

	store, _ := dao.GetStoreDetail(dao.GetDB(), goodsOrder.JxStoreID, goodsOrder.VendorID, goodsOrder.VendorOrgCode)
	sfTotalPrice += store.FreightMarkup

	orderStatus := utils.Str2Int64(order.VendorStatus)
	switch orderStatus {
	case sfps2.OrderStatusNewOrder: //1：订单创建
		order.DesiredFee = int64(sfTotalPrice)
		order.ActualFee = sfActualPrice
		order.Status = model.WaybillStatusNew //5 带调度
	case sfps2.OrderStatusTakeOrder: //10：配送员接单
		order.DesiredFee = int64(sfTotalPrice)
		order.Status = model.WaybillStatusCourierAssigned //12
		order.Remark = order.CourierName + "，" + order.CourierMobile
	case sfps2.OrderStatusArrivedStore:
		order.DesiredFee = int64(sfTotalPrice)
		order.Status = model.WaybillStatusCourierArrived
	case sfps2.OrderStatusRiderArriving:
		order.DesiredFee = int64(sfTotalPrice)
		order.Status = model.WaybillStatusDelivering
	case sfps2.OrderStatusFinished:
		order.DesiredFee = int64(sfTotalPrice)
		order.Status = model.WaybillStatusDelivered
	case sfps2.OrderStatusOrderCancel, sfps2.OrderStatusRiderCancel:
		order.Status = model.WaybillStatusCanceled
	case sfps2.OrderStatusError:
		order.Status = model.WaybillStatusDeliverFailed // 22
	default:
		globals.SugarLogger.Warnf("onWaybillMsg unknown msg:%v", msg)
	}

	if err := partner.CurOrderManager.OnWaybillStatusChanged(order); err != nil {
		return sfps2.Err2CallbackResponse(err)
	}

	switch order.OrderVendorID {
	case model.VendorIDDD:
		Lng, Lat, _ := partner.GetRidderPositionGetter(order.WaybillVendorID).GetRidderPosition(nil, order.VendorOrderID, order.VendorOrderID, order.VendorWaybillID, order.VendorWaybillID2)
		tiktokStatusPush(order, orderStatus, utils.Float64ToStr(Lng), utils.Float64ToStr(Lat), goodsOrder.VendorOrgCode)
	case model.VendorIDTaoVegetable, model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDJD:
		delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID, order.Status) // 骑手位置更新
		if goodsOrder.VendorID == model.VendorIDTaoVegetable && orderStatus == sfps2.OrderStatusTakeOrder {
			tao_vegetable.PushDelivererChangeInfo(goodsOrder, order, tao.TaoDeliveryTypeSF)
		}
	}
	return sfps2.Err2CallbackResponse(nil)
}

//转发到果园
func pushCallbackToGy(urlIndex string, msg interface{}, serverType string) {
	var (
		err     error
		client  = &http.Client{}
		request *http.Request
	)

	b, _ := json.Marshal(msg)
	if serverType == model.ServerTypeFruits {
		switch urlIndex {
		case sfps2.UrlIndexRiderException:
			request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfAbnormal", strings.NewReader(string(b)))
		default:
			//fullUrl := utils.GenerateGetURL("http://callback-jxgy.jxc4.com/SFPS/SfOrder", "", map[string]interface{}{"sign": sign})
			//request, err = http.NewRequest(http.MethodPost, fullUrl, strings.NewReader(string(b)))
			request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfOrder", strings.NewReader(string(b)))
		}
	} else if serverType == model.ServerTypePet {
		switch urlIndex {
		case sfps2.UrlIndexRiderException:
			request, err = http.NewRequest(http.MethodPost, "http://callback-gblm.jxc4.com/SFPS/SfAbnormal", strings.NewReader(string(b)))
		default:
			//fullUrl := utils.GenerateGetURL("http://callback-jxgy.jxc4.com/SFPS/SfOrder", "", map[string]interface{}{"sign": sign})
			//request, err = http.NewRequest(http.MethodPost, fullUrl, strings.NewReader(string(b)))
			request, err = http.NewRequest(http.MethodPost, "http://callback-gblm.jxc4.com/SFPS/SfOrder", strings.NewReader(string(b)))
		}
	}

	if err != nil {
		globals.SugarLogger.Debugf("pushCallbackToGy req err=%v", err)
		return
	}
	request.Header.Set("Content-Type", "application/json; charset=UTF-8")
	resp, err := client.Do(request)
	ioutil.ReadAll(resp.Body)
}

func tiktokStatusPush(order *model.Waybill, orderStatus int64, lng, lat, vendorOrgCode string) {
	result := &utils.RiderInfo{
		OrderId:               order.VendorOrderID,
		ThirdCarrierOrderId:   order.VendorWaybillID,
		CourierName:           order.CourierName,
		CourierPhone:          order.CourierMobile,
		LogisticsProviderCode: utils.SFPSCode,
		LogisticsStatus:       order.Status,
		OpCode:                "",
		Latitude:              lat,
		Longitude:             lng,
	}
	switch orderStatus {
	case sfps2.OrderStatusNewOrder:
		result.LogisticsStatus = model.WaybillStatusNew
		result.LogisticsContext = model.RiderWaitRider
	case sfps2.OrderStatusTakeOrder:
		result.LogisticsStatus = model.WaybillStatusCourierAssigned // 分配骑手
		result.LogisticsContext = model.RiderWaitGetGoods
	case sfps2.OrderStatusRiderArriving:
		result.LogisticsStatus = model.WaybillStatusDelivering
		result.LogisticsContext = model.RiderGetOrderDelivering
	case sfps2.OrderStatusFinished:
		result.LogisticsStatus = model.WaybillStatusDelivered
		result.LogisticsContext = model.RiderGetOrderDelivered
	case sfps2.OrderStatusOrderCancel, sfps2.OrderStatusRiderCancel:
		result.LogisticsStatus = model.WaybillStatusCanceled
		result.LogisticsContext = model.RiderGetOrderCanceled
	case sfps2.OrderStatusError:
		result.LogisticsStatus = model.WaybillStatusDeliverFailed
		result.LogisticsContext = model.RiderGetOrderDeliverFailed
	case sfps2.OrderStatusArrivedStore:
		result.LogisticsStatus = model.WaybillStatusCourierArrived
		result.LogisticsContext = model.RiderToStore
	default:
		result.LogisticsStatus = 0
		result.LogisticsContext = model.RiderGetOrderDeliverOther
	}
	delivery.PullTiktokRiderInfo(result, vendorOrgCode)
}

// OnWaybillExceptSF 异常报备
func OnWaybillExceptSF(msg *sfps2.RiderException) (retVal *sfps2.CallbackResponse) {
	jxutils.CallMsgHandler(func() {
		order := &model.Waybill{
			VendorWaybillID:  msg.SFOrderID,
			VendorWaybillID2: utils.Int2Str(msg.ExID),
			WaybillVendorID:  model.VendorIDSFPS,
			CourierName:      msg.OperatorName,
			CourierMobile:    "",
			Status:           model.WaybillStatusUnknown, // todo 这里要再确定一下是否只要收到订单异常消息就只简单当成一个消息
			VendorStatus:     utils.Float64ToStr(msg.OrderStatus),
			StatusTime:       utils.Timestamp2Time(int64(msg.PushTime)),
		}
		goods, _ := dao.GetSimpleOrder(dao.GetDB(), msg.ShopOrderID)
		order.VendorOrderID, order.OrderVendorID = goods.VendorOrderID, goods.VendorID
		retVal = sfps2.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order))
	}, jxutils.ComposeUniversalOrderID(msg.ShopOrderID, model.VendorIDSFPS))
	return retVal
}

// GetWaybillByStatus 根据orderStatus 获取waybill和goodsOrder结构
func GetWaybillByStatus(urlIndex string, msg interface{}) (waybill *model.Waybill, good2 *model.GoodsOrder) {
	globals.SugarLogger.Debugf("GetWaybillByStatus msg=%s", utils.Format4Output(msg, false))

	waybill = getWaybillByStatus(urlIndex, msg)
	//获取系统订单
	var good *model.GoodsOrder
	sql := `SELECT * FROM goods_order WHERE vendor_order_id = ? ORDER BY order_created_at DESC  LIMIT 1 OFFSET 0`
	sqlParams := []interface{}{waybill.VendorOrderID}
	err := dao.GetRow(dao.GetDB(), &good, sql, sqlParams)

	if err != nil || good == nil || good.VendorOrderID == "" {
		waybill.OrderVendorID = 0
	} else {
		waybill.OrderVendorID = good.VendorID
		waybill.VendorOrderID = good.VendorOrderID
	}
	return waybill, good
}

//转换顺丰回调信息
func getWaybillByStatus(urlIndex string, msg interface{}) (waybill *model.Waybill) {
	waybill = &model.Waybill{}
	switch urlIndex {
	case sfps2.UrlIndexRiderStatus:
		retVal := msg.(sfps2.RiderStatus)
		waybill = &model.Waybill{
			VendorWaybillID: retVal.SFOrderID,
			WaybillVendorID: model.VendorIDSFPS,
			VendorOrderID:   retVal.ShopOrderID,
			CourierName:     retVal.OperatorName,
			CourierMobile:   retVal.OperatorPhone,
			VendorStatus:    utils.Float64ToStr(retVal.OrderStatus),
			StatusTime:      utils.Timestamp2Time(int64(retVal.PushTime)),
			Remark:          retVal.StatusDesc,
		}
		if retVal.PushTime == 0 {
			waybill.StatusTime = time.Now()
		}
	case sfps2.UrlIndexRiderRecall:
		retVal := msg.(sfps2.RiderRecall)
		waybill = &model.Waybill{
			VendorWaybillID: retVal.SFOrderID,
			WaybillVendorID: model.VendorIDSFPS,
			VendorOrderID:   retVal.ShopOrderID,
			VendorStatus:    utils.Float64ToStr(retVal.OrderStatus),
			StatusTime:      utils.Timestamp2Time(int64(retVal.PushTime)),
			Remark:          retVal.StatusDesc,
		}
		if retVal.PushTime == 0 {
			waybill.StatusTime = time.Now()
		}
	case sfps2.UrlIndexOrderComplete:
		retVal := msg.(sfps2.OrderComplete)
		waybill = &model.Waybill{
			VendorWaybillID: retVal.SfOrderID,
			WaybillVendorID: model.VendorIDSFPS,
			VendorOrderID:   retVal.ShopOrderID,
			CourierName:     retVal.OperatorName,
			VendorStatus:    utils.Float64ToStr(retVal.OrderStatus),
			StatusTime:      utils.Timestamp2Time(int64(retVal.PushTime)),
			Remark:          retVal.StatusDesc,
		}
		if retVal.PushTime == 0 {
			waybill.StatusTime = time.Now()
		}
	case sfps2.UrlIndexSFCancel:
		retVal := msg.(sfps2.SFCancel)
		waybill = &model.Waybill{
			VendorWaybillID: retVal.SFOrderID,
			WaybillVendorID: model.VendorIDSFPS,
			VendorOrderID:   retVal.ShopOrderID,
			CourierName:     retVal.OperatorName,
			VendorStatus:    utils.Float64ToStr(retVal.OrderStatus),
			StatusTime:      utils.Timestamp2Time(int64(retVal.PushTime)),
			Remark:          retVal.StatusDesc,
		}
		if retVal.PushTime == 0 {
			waybill.StatusTime = time.Now()
		}
	default:
		return nil
	}
	return waybill
}

//转换原始数据 转发果园
func changeToRaw(urlIndex string, msg interface{}) (retVal map[string]interface{}) {
	retVal = make(map[string]interface{})
	globals.SugarLogger.Debugf("%s, msg=%s", urlIndex, utils.Format4Output(msg, false))
	switch urlIndex {
	case sfps2.UrlIndexRiderStatus:
		temp := msg.(sfps2.RiderStatus)
		retVal["shop_id"] = temp.ShopId
		retVal["sf_order_id"] = temp.SFOrderID
		retVal["shop_order_id"] = temp.ShopOrderID
		retVal["url_index"] = temp.UrlIndex
		retVal["operator_name"] = temp.OperatorName
		retVal["operator_phone"] = temp.OperatorPhone
		retVal["rider_lng"] = temp.RiderLng
		retVal["rider_lat"] = temp.RiderLat
		retVal["order_status"] = temp.OrderStatus
		retVal["status_desc"] = temp.StatusDesc
		retVal["sf_ucode"] = temp.SFUCode
		retVal["push_time"] = temp.PushTime
	case sfps2.UrlIndexRiderRecall:
		temp := msg.(sfps2.RiderRecall)
		retVal["order_status"] = temp.OrderStatus
		retVal["push_time"] = temp.PushTime
		retVal["sf_order_id"] = temp.SFOrderID
		retVal["shop_id"] = temp.ShopId
		retVal["shop_order_id"] = temp.ShopOrderID
		retVal["url_index"] = temp.UrlIndex
		retVal["status_desc"] = temp.StatusDesc
	case sfps2.UrlIndexOrderComplete:
		temp := msg.(sfps2.OrderComplete)
		retVal["operator_name"] = temp.OperatorName
		retVal["operator_phone"] = temp.OperatorPhone
		retVal["order_status"] = temp.OrderStatus
		retVal["push_time"] = temp.PushTime
		retVal["receiRpt_type"] = temp.ReceiRptType
		retVal["rider_lat"] = temp.RiderLat
		retVal["rider_lng"] = temp.RiderLng
		retVal["sf_order_id"] = temp.SfOrderID
		retVal["sf_ucode"] = temp.SfUcode
		retVal["shop_id"] = temp.ShopId
		retVal["shop_order_id"] = temp.ShopOrderID
		retVal["status_desc"] = temp.StatusDesc
		retVal["url_index"] = temp.UrlIndex
	case sfps2.UrlIndexSFCancel:
		temp := msg.(sfps2.SFCancel)
		retVal["cancel_reason"] = temp.CancelReason
		retVal["cancel_code"] = temp.CancelCode
		retVal["operator_name"] = temp.OperatorName
		retVal["operator_phone"] = temp.OperatorPhone
		retVal["order_status"] = temp.OrderStatus
		retVal["push_time"] = temp.PushTime
		retVal["rider_lat"] = temp.RiderLat
		retVal["rider_lng"] = temp.RiderLng
		retVal["sf_order_id"] = temp.SFOrderID
		retVal["sf_ucode"] = temp.SFUCode
		retVal["shop_id"] = temp.ShopId
		retVal["shop_order_id"] = temp.ShopOrderID
		retVal["url_index"] = temp.UrlIndex
		retVal["status_desc"] = temp.StatusDesc
	}
	//签名
	//b, _ := json.Marshal(retVal)
	//sign := api.SfPsAPI.SignParam(b)
	//retVal["sign"] = sign
	return retVal
}

//  辅助函数

//获取订单来源标识符
func GetVendorSource(vendorID int) (source string) {
	switch vendorID {
	case model.VendorIDMTWM:
		source = sfps2.OrderSourceMt
	case model.VendorIDELM:
		source = sfps2.OrderSourceELM
	case model.VendorIDEBAI:
		source = sfps2.OrderSourceEBAI
	case model.VendorIDDD:
		source = "抖音"
	case model.VendorIDJD:
		source = "京东"
	case model.VendorIDJX:
		source = "京西"
	default:
		source = "其他"
	}
	return source
}

func getReallyStoreID(storeID, jxStoreID int) int {
	if storeID == 0 && jxStoreID == 0 {
		return 0
	}
	if storeID == 0 {
		return jxStoreID
	} else {
		return storeID
	}
}

func (c *DeliveryHandler) GetPlatformBalance() (balance int64, err error) {
	return 0, fmt.Errorf("暂不支持此功能")
}
func (c *DeliveryHandler) BalanceRecharge(param *utils.RechargeBalance) (url string, err error) {
	return "", fmt.Errorf("此平台暂不支持充值")
}
