package jdapi

import (
	"errors"
	"fmt"
	"git.rosy.net.cn/jx-callback/globals"
	"strings"

	"git.rosy.net.cn/baseapi"

	"git.rosy.net.cn/baseapi/utils"
)

const (
	AfsPicPrefix      = "http://img10.360buyimg.com/o2o"
	AfsPicPrefixHttps = "https://img10.360buyimg.com/o2o"
)

const (
	DeliveryStatusWait4Grap              = "10" // 等待抢单
	DeliveryStatusAccepted               = "20" // 已抢单
	DeliveryStatusCourierCanceled        = "21" // 配送员取消抢单，等待重新抢单
	DeliveryStatusCourierChaged          = "22" // 更换配送员
	DeliveryStatusCourierArrived         = "23" // 配送员已到店
	DeliveryStatusFailedGetGoods         = "25" // 取货失败
	DeliveryStatusFailedGetGoodsRejected = "26" // 取货失败审核驳回
	DeliveryStatusFailedGetGoodsWaiting  = "27" // 取货失败待审核

	// 【新增接口】商家处理订单上报异常接口上线
	DeliveryStatusRidderAbnormal        = "28" // 骑士异常上报
	DeliveryStatusRidderAbnormalHandled = "29" // 骑士异常上报已处理

	DeliveryStatusGotGoods       = "30" // 取货完成
	DeliveryStatusFailedDelivery = "35" // 投递失败
	DeliveryStatusFinished       = "40" // 已完成
)

const (
	PromotionTypeNormal           = 1
	PromotionTypeSeckill          = 2
	PromotionTypeDirectDown       = 3
	PromotionTypeLimitedTime      = 4
	PromotionTypeAddMoneyBuy      = 1202
	PromotionTypeOverflowGiveGift = 1203
	PromotionTypeBuyGiveGift      = 6
)

const (
	FreightDiscountTypeByShop     = 8  // 8:商家满免运费
	FreightDiscountTypeByVip      = 7  // 7:VIP免运费
	FreightDiscountTypeByActivity = 12 // 12:首单地推满免运费
	FreightDiscountTypeByCoupons  = 15 // 15:运费券
)

const (
	UserApplyCancelWaitMinute = 15 // 用户申请取消订单后待处理的最大等待时间（分钟），超时自动同意
)

const (
	QueryOrderRetryCount = 1 // 因为京东到家当前不存在的订单也返回-4，暂时不重试
)

const (
	AfsApproveTypeRefund      = 1 // 退款
	AfsApproveTypeReturnGoods = 2 // 退货
	AfsApproveTypeRefused     = 3 // 驳回
)

const (
	AfsReasonTypeGoodsQuality  = 201 // 商品质量问题
	AfsReasonTypeWrongGoods    = 202 // 送错货
	AfsReasonTypeMissingGoods  = 203 // 缺件少件
	AfsReasonTypeNoGoods       = 501 // 全部商品未收到
	AfsReasonTypeDamagedGoods  = 208 // 包装脏污有破损
	AfsReasonTypeGoodsQuantity = 207 // 缺斤少两
	// AfsReasonTypeAgreedByMerchant = 209 // 与商家协商一致，2019/09/01取消
	AfsReasonTypeGoodsAbsent      = 210 // 商家通知我缺货
	AfsReasonTypeGoodsSizeNoSame  = 302 // 大小尺寸与商品描述不符
	AfsReasonTypeGoodsColorNoSame = 303 // 实物与原图不符
	AfsReasonWrongPurchase        = 402 // 不想要了  //此原因已剔除
	AfsReasonNotReceivedIntime    = 502 // 未在时效内送达
)

const (
	AfsDealTypeRefund            = "10" // 仅退款
	AfsDealTypeDirectCompensate  = "30" // 直赔
	AfsDealTypeReturnGoodsRefund = "40" // 退货退款
)

const (
	ComplaintReason1   = 1   //达达态度恶劣;
	ComplaintReason2   = 2   //接单后未取货;
	ComplaintReason3   = 3   //取货速度太慢;
	ComplaintReason4   = 4   //送货速度太慢;
	ComplaintReason5   = 5   //货品未送达;
	ComplaintReason6   = 6   //货品损坏;
	ComplaintReason7   = 7   //违规收取顾客小费;
	ComplaintReason11  = 11  //达达衣冠不整;
	ComplaintReason69  = 69  //达达恶意取消订单;
	ComplaintReason71  = 71  //达达提前点击取货/送达;
	ComplaintReason214 = 214 //达达无标准保温箱;
)

const (
	ModifySellerDeliveryNo = "359459" // 京东自配送账号，不需要达达转字配送
)

type AfsSkuDiscount struct {
	DetailDiscountType int   `json:"detailDiscountType"`
	DiscountType       int   `json:"discountType"`
	PlatPayMoney       int64 `json:"platPayMoney"`
	VenderPayMoney     int64 `json:"venderPayMoney"`
}

type AfsServiceDetail struct {
	SkuIDIsv      string  `json:"skuIdIsv"`
	WareID        int64   `json:"wareId"`
	WareName      string  `json:"wareName"`
	WareNum       int     `json:"wareNum"`
	SkuCount      int     `json:"skuCount"`
	PromotionType int     `json:"promotionType"`
	Weight        float64 `json:"weight"`

	AfsMoney     int64 `json:"afsMoney"`
	PlatPayMoney int64 `json:"platPayMoney"`

	AfsSkuDiscountList []*AfsSkuDiscount `json:"afsSkuDiscountList"`
}

type AfsServiceResponse struct {
	AfsServiceID        int64           `json:"afsServiceId"`
	AfsServiceOrder     string          `json:"afsServiceOrder"`
	AfsServiceState     int             `json:"afsServiceState"`
	CreateTime          *utils.JavaDate `json:"createTime"`
	UpdateTime          *utils.JavaDate `json:"updateTime"`
	CustomerMobilePhone string          `json:"customerMobilePhone"`
	CustomerName        string          `json:"customerName"`
	OrderID             string          `json:"orderId"`
	OrderSource         int             `json:"orderSource"`
	OrderStatus         int             `json:"orderStatus"`
	OrderType           int             `json:"orderType"`
	PickwareAddress     string          `json:"pickwareAddress"`

	OrderFreightMoney     int64 `json:"orderFreightMoney"`
	AfsFreight            int64 `json:"afsFreight"`
	PackagingMoney        int64 `json:"packagingMoney"`
	TongchengFreightMoney int64 `json:"tongchengFreightMoney"`
	MealBoxMoney          int64 `json:"mealBoxMoney"`

	QuestionDesc    string `json:"questionDesc"`
	QuestionPic     string `json:"questionPic"`
	QuestionTypeCid int    `json:"questionTypeCid"`

	ApplyDeal      string `json:"applyDeal"`
	DeliveryState  string `json:"deliveryState"`
	DeliveryMan    string `json:"deliveryMan"`
	DeliveryMobile string `json:"deliveryMobile"`

	StationID           string `json:"stationId"`
	StationName         string `json:"stationName"`
	StationNumOutSystem string `json:"stationNumOutSystem"`
	VenderID            string `json:"venderId"`

	AfsDetailList []*AfsServiceDetail `json:"afsDetailList"`
}

type OAOSAdjustDTO struct {
	SkuID    int64  `json:"skuId,omitempty"`
	OutSkuID string `json:"outSkuId,omitempty"`
	SkuCount int    `json:"skuCount"`
}

type VenderAfsSkuDTO struct {
	SkuID         int64 `json:"skuId"`
	SkuCount      int   `json:"skuCount"`
	PromotionType int   `json:"promotionType"`
}

type OrderSettlementInfo struct {
	AllAfterSaleFreight           int64           `json:"allAfterSaleFreight"`
	AllAfterSalePackageMoney      int64           `json:"allAfterSalePackageMoney"`
	BillTime                      *utils.JavaDate `json:"billTime"`
	DistanceFreightMoney          int64           `json:"distanceFreightMoney"`
	FreightCommission             int64           `json:"freightCommission"`
	GoodsCommission               int64           `json:"goodsCommission"`
	GuaranteedCommission          int64           `json:"guaranteedCommission"`
	OrderCashOnDeliveryMoney      int64           `json:"orderCashOnDeliveryMoney"`
	OrderGiftCardMoney            int64           `json:"orderGiftCardMoney"`
	OrderID                       int64           `json:"orderId"`
	OrgCode                       string          `json:"orgCode"`
	PackageCommission             int64           `json:"packageCommission"`
	PackageMoney                  int64           `json:"packageMoney"`
	PlatDeliveryFreight           int64           `json:"platDeliveryFreight"`
	PlatFreightDiscountMoney      int64           `json:"platFreightDiscountMoney"`
	PlatOrderGoodsDiscountMoney   int64           `json:"platOrderGoodsDiscountMoney"`
	PlatSkuGoodsDiscountMoney     int64           `json:"platSkuGoodsDiscountMoney"`
	SettlementAmount              int64           `json:"settlementAmount"`
	StationNo                     string          `json:"stationNo"`
	UserActualPaidGoodsMoney      int64           `json:"userActualPaidGoodsMoney"`
	VenderDeliveryFreight         int64           `json:"venderDeliveryFreight"`
	VenderFreightDiscountMoney    int64           `json:"venderFreightDiscountMoney"`
	VenderOrderGoodsDiscountMoney int64           `json:"venderOrderGoodsDiscountMoney"`
	VenderPaidTips                int64           `json:"venderPaidTips"`
	VenderSkuGoodsDiscountMoney   int64           `json:"venderSkuGoodsDiscountMoney"`
}

type OrderProductInfo struct {
	AdjustMode        int     `json:"adjustMode"`
	CanteenMoney      int     `json:"canteenMoney"`
	CategoryID        string  `json:"categoryId"`
	FirstCategoryName string  `json:"firstCategoryName"`
	IsGift            bool    `json:"isGift"`
	PromotionType     int     `json:"promotionType"`
	SkuCount          int     `json:"skuCount"`
	SkuID             int     `json:"skuId"`
	SkuJdPrice        int     `json:"skuJdPrice"`
	SkuName           string  `json:"skuName"`
	SkuSpuID          int     `json:"skuSpuId"`
	SkuStockOwner     int     `json:"skuStockOwner"`
	SkuStorePrice     int     `json:"skuStorePrice"`
	SkuWeight         float64 `json:"skuWeight"`
	UpcCode           string  `json:"upcCode,omitempty"`
	SpecialServiceTag string  `json:"specialServiceTag,omitempty"`
}

type OrderInfo struct {
	AdjustCount                         int     `json:"adjustCount"`
	AdjustID                            int     `json:"adjustId"`
	AdjustIsExists                      bool    `json:"adjustIsExists"`
	AppVersion                          string  `json:"appVersion"`
	ArtificerPortraitURL                string  `json:"artificerPortraitUrl"`
	BusinessTag                         string  `json:"businessTag"`
	BusinessType                        int     `json:"businessType"`
	BuyerCity                           string  `json:"buyerCity"`
	BuyerCityName                       string  `json:"buyerCityName"`
	BuyerCoordType                      int     `json:"buyerCoordType"`
	BuyerCountry                        string  `json:"buyerCountry"`
	BuyerCountryName                    string  `json:"buyerCountryName"`
	BuyerFullAddress                    string  `json:"buyerFullAddress"`
	BuyerFullName                       string  `json:"buyerFullName"`
	BuyerIP                             int     `json:"buyerIp"`
	BuyerLat                            float64 `json:"buyerLat"`
	BuyerLng                            float64 `json:"buyerLng"`
	BuyerMobile                         string  `json:"buyerMobile"`
	BuyerPin                            string  `json:"buyerPin"`
	BuyerPinType                        int     `json:"buyerPinType"`
	BuyerPoi                            string  `json:"buyerPoi"`
	BuyerProvince                       string  `json:"buyerProvince"`
	CancelDeadline                      string  `json:"cancelDeadline"`
	CancelOperator                      string  `json:"cancelOperator"`
	CancelOrderIsReadable               bool    `json:"cancelOrderIsReadable"`
	CancelRequestTime                   string  `json:"cancelRequestTime"`
	ClientOrderPreStartDeliveryTime     string  `json:"clientOrderPreStartDeliveryTime"`
	DeliveryBillNo                      string  `json:"deliveryBillNo"`
	DeliveryCarrierName                 string  `json:"deliveryCarrierName"`
	DeliveryCarrierNo                   string  `json:"deliveryCarrierNo"` // 此字段会在配送变化后变化
	DeliveryDelayAgreed                 int     `json:"deliveryDelayAgreed"`
	DeliveryPackageVolume               float64 `json:"deliveryPackageVolume"`
	DeliveryPackageWeight               float64 `json:"deliveryPackageWeight"`
	DeliveryStationName                 string  `json:"deliveryStationName"`
	DeliveryStationNo                   string  `json:"deliveryStationNo"`
	DeliveryStationNoIsv                string  `json:"deliveryStationNoIsv"`
	DeliveryType                        int     `json:"deliveryType"`
	EquipmentID                         string  `json:"equipmentId"`
	GrabMark                            int     `json:"grabMark"`
	IndustryTag                         int     `json:"industryTag"`
	IsDeleted                           bool    `json:"isDeleted"`
	IsGroupon                           bool    `json:"isGroupon"`
	IsJDGetCash                         bool    `json:"isJDGetCash"`
	LastFourDigitsOfBuyerMobile         string  `json:"lastFourDigitsOfBuyerMobile"`
	LocalDeliveryMoney                  int     `json:"localDeliveryMoney"`
	MerchantPaymentDistanceFreightMoney int     `json:"merchantPaymentDistanceFreightMoney"`
	OrderAcceptTime                     string  `json:"orderAcceptTime"`
	OrderAdditionFreightMoney           int     `json:"orderAdditionFreightMoney"`
	OrderAgingType                      int     `json:"orderAgingType"`
	OrderBalanceUsed                    int     `json:"orderBalanceUsed"`
	OrderBaseFreightMoney               int     `json:"orderBaseFreightMoney"`
	OrderBaseReceivableFreight          int     `json:"orderBaseReceivableFreight"`
	OrderBuyerPayableMoney              int     `json:"orderBuyerPayableMoney"`
	OrderBuyerRemark                    string  `json:"orderBuyerRemark"`
	OrderCancelRemark                   string  `json:"orderCancelRemark"`
	OrderCancelTime                     string  `json:"orderCancelTime"`
	OrderDiscountMoney                  int     `json:"orderDiscountMoney"`
	OrderDistanceStepFreight            int     `json:"orderDistanceStepFreight"`
	OrderFinanceOrgCode                 int     `json:"orderFinanceOrgCode"`
	OrderFreightMoney                   int     `json:"orderFreightMoney"`
	OrderGoodsMoney                     int     `json:"orderGoodsMoney"`
	OrderID                             int64   `json:"orderId"`
	OrderInvoiceOpenMark                int     `json:"orderInvoiceOpenMark"`
	OrderIsClosed                       bool    `json:"orderIsClosed"`
	OrderJingdouMoney                   int     `json:"orderJingdouMoney"`
	OrderLadderFreightMoney             int     `json:"orderLadderFreightMoney"`
	OrderNum                            int     `json:"orderNum"`
	OrderPayType                        int     `json:"orderPayType"`
	OrderPreDeliveryTime                string  `json:"orderPreDeliveryTime"`
	OrderPreEndDeliveryTime             string  `json:"orderPreEndDeliveryTime"`
	OrderPreStartDeliveryTime           string  `json:"orderPreStartDeliveryTime"`
	OrderPurchaseTime                   string  `json:"orderPurchaseTime"`
	OrderReceivableFreight              int     `json:"orderReceivableFreight"`
	OrderSkuType                        int     `json:"orderSkuType"`
	OrderStartTime                      string  `json:"orderStartTime"`
	OrderStatus                         int     `json:"orderStatus"`
	OrderStatusTime                     string  `json:"orderStatusTime"`
	OrderStockOwner                     int     `json:"orderStockOwner"`
	OrderTakeSelfCode                   string  `json:"orderTakeSelfCode"`
	OrderTotalMoney                     int     `json:"orderTotalMoney"`
	OrderType                           int     `json:"orderType"`
	OrderVenderChargeMoney              int     `json:"orderVenderChargeMoney"`
	OrgCode                             string  `json:"orgCode"`
	PackagingMoney                      int     `json:"packagingMoney"`
	PayChannel                          int     `json:"payChannel"`
	PickDeadline                        string  `json:"pickDeadline"`
	PickMark                            int     `json:"pickMark"`
	PlatformPointsDeductionMoney        int     `json:"platformPointsDeductionMoney"`
	PrescriptionDTO                     struct {
		IsRigorous bool `json:"isRigorous"`
	} `json:"prescriptionDTO"`
	PrintMark                 int                 `json:"printMark"`
	ProduceStationName        string              `json:"produceStationName"`
	ProduceStationNo          string              `json:"produceStationNo"`
	ProduceStationNoIsv       string              `json:"produceStationNoIsv"`
	Product                   []*OrderProductInfo `json:"product"`
	SrcInnerOrderID           int                 `json:"srcInnerOrderId"`
	SrcInnerType              int                 `json:"srcInnerType"`
	SrcOrderID                string              `json:"srcOrderId"`
	SrcOrderType              int                 `json:"srcOrderType"`
	SrcPlatID                 int                 `json:"srcPlatId"`
	StoreLat                  float64             `json:"storeLat"`
	StoreLng                  float64             `json:"storeLng"`
	Tips                      int                 `json:"tips"`
	Ts                        string              `json:"ts"`
	UpdatePin                 string              `json:"updatePin"`
	UserTip                   int                 `json:"userTip"`
	VenderBalanceDeductMoney  int                 `json:"venderBalanceDeductMoney"`
	VenderIntegralDeductMoney int                 `json:"venderIntegralDeductMoney"`
	VenderProcessResult       string              `json:"venderProcessResult"`
	Yn                        bool                `json:"yn"`
}

type OrderQueryParam struct {
	PageNo   int   `json:"pageNo,omitempty"`   // 当前页数,默认：1
	PageSize int   `json:"pageSize,omitempty"` // 每页条数,默认：20，最大值100
	OrderID  int64 `json:"orderId,omitempty"`

	OrderPurchaseTimeBegin string `json:"orderPurchaseTime_begin,omitempty"` // 购买成交时间-支付(开始)
	OrderPurchaseTimeEnd   string `json:"orderPurchaseTime_end,omitempty"`   // 购买成交时间-支付(结束)
	OrderStatus            int    `json:"orderStatus,omitempty"`

	DeliveryStationNo    string `json:"deliveryStationNo,omitempty"`    // 到家门店编码
	DeliveryStationNoIsv string `json:"deliveryStationNoIsv,omitempty"` // 商家门店编码
}

type SonTag struct {
	MqProcessTime string `json:"mqProcessTime"`
	OperTime      string `json:"operTime"`
	TagCode       int    `json:"tagCode"`
	CodeName      string `json:"codeName"`
	OperPin       string `json:"operPin"`
	OperName      int    `json:"operName"`
	MsgContent    string `json:"msgContent"`
}

type OrderTrack struct {
	SonTagList      []*SonTag `json:"sonTagList"`
	IsThirdCarry    int       `json:"isThirdCarry"`
	OperFrom        string    `json:"operFrom"`
	MqProcessTime   string    `json:"mqProcessTime"`
	TagIcon         string    `json:"tagIcon"`
	OperTime        string    `json:"operTime"`
	ThirdCarry      int       `json:"thirdCarry"`
	TagTitle        string    `json:"tagTitle"`
	CodeName        string    `json:"codeName"`
	TagCode         int       `json:"tagCode"`
	OperPin         string    `json:"operPin"`
	OperName        string    `json:"operName"`
	Care            bool      `json:"care"`
	MsgContent      string    `json:"msgContent"`
	MsgContentApp   string    `json:"msgContentApp"`
	DoNotCareReason string    `json:"doNotCareReason"`
}

var (
	ErrCanNotFindOrder = errors.New("can not find order")
)

var (
	orderOperationResultParser = genNoPageResultParser("code", "detail", "detail", "0")
)

// 订单列表查询接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=ba3027848c3c4fda9674966e2a466482
func (a *API) OrderQuery(jdParams map[string]interface{}) (retVal []interface{}, totalCount int, err error) {
	// 最多试三次
	for i := 0; i < QueryOrderRetryCount; i++ {
		retVal, totalCount, err = a.AccessAPIHavePage("order/es/query", jdParams, nil, nil, nil)
		if err != nil {
			//if err2, ok := err.(*utils.ErrorWithCode); ok {
			//	if err2.IntCode() == -4 {
			//		continue
			//	}
			//}
			return retVal, totalCount, err
		}
		break
	}
	return retVal, totalCount, err
}

// orderFreightMoney 基础运费
// tips 商家承担小费
// merchantPaymentDistanceFreightMoney 取件服务费(开票)(正向单展示远距离运费;售后单则展示达达售后运费)
// orderBaseFreightMoney ?
func (a *API) QuerySingleOrder(orderId string) (map[string]interface{}, error) {
	jdParams := make(map[string]interface{})
	jdParams["orderId"] = orderId
	result, _, err := a.OrderQuery(jdParams)
	if err != nil {
		return nil, err
	}
	if len(result) == 0 {
		return nil, ErrCanNotFindOrder
	}
	return result[0].(map[string]interface{}), nil
}

func (a *API) OrderQuery2(queryParam *OrderQueryParam) (retVal []*OrderInfo, totalCount int, err error) {
	orderList, totalCount, err := a.OrderQuery(utils.Struct2MapByJson(queryParam))
	if err == nil {
		err = JdMap2StructByJson(orderList, &retVal, true)
	}
	return retVal, totalCount, err
}

func (a *API) QuerySingleOrder2(orderID string) (orderInfo *OrderInfo, err error) {
	orderList, _, err := a.OrderQuery2(&OrderQueryParam{
		OrderID: utils.Str2Int64(orderID),
	})
	if err == nil {
		if len(orderList) > 0 {
			orderInfo = orderList[0]
		} else {
			err = ErrCanNotFindOrder
		}
	}
	return orderInfo, err
}

// 商家确认接单接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=c1a15129d1374e9da7fa35487f878604
func (a *API) OrderAcceptOperate(orderId string, isAgreed bool, userName string) error {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"isAgreed": utils.Bool2String(isAgreed),
		"operator": utils.GetAPIOperator(userName),
	}

	// 接单
	_, err := a.AccessAPINoPage("ocs/orderAcceptOperate", jdParams, nil, nil, orderOperationResultParser)
	// 打印
	printResult, err2 := a.AccessAPINoPage("bm/open/api/order/printOrder", map[string]interface{}{
		"orderId": utils.Str2Int64(orderId),
	}, nil, nil, nil)
	if err2 != nil {
		globals.SugarLogger.Debugf("打印订单错误: %s,%v", utils.Format4Output(printResult, false), err2)
	}
	return err
}

// 拣货完成且众包配送接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=ed93745b86c6487eaaea5f55a84785ac
func (a *API) OrderJDZBDelivery(orderId string, userName string) (detail string, err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"operator": utils.GetAPIOperator(userName),
	}
	result, err := a.AccessAPINoPage("bm/open/api/order/OrderJDZBDelivery", jdParams, nil, nil, orderOperationResultParser)
	if err == nil {
		return utils.Interface2String(result), nil
	}
	return "", err
}

// 订单拣货完成且商家自送
// https://openapi.jddj.com/djapi/bm/open/api/order/OrderSerllerDelivery
func (a *API) OrderJDZBStoreDelivery(orderId string, userName string) (detail string, err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"operator": utils.GetAPIOperator(userName),
	}
	result, err := a.AccessAPINoPage("bm/open/api/order/OrderSerllerDelivery", jdParams, nil, nil, orderOperationResultParser)
	if err == nil {
		return utils.Interface2String(result), nil
	}
	return "", err
}

// 订单拣货完成且顾客自提
// https://openapi.jddj.com/djapi/bm/open/api/order/OrderSelfMention
func (a *API) OrderJDZBSelfDelivery(orderId string, userName string) (detail string, err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"operator": utils.GetAPIOperator(userName),
	}
	result, err := a.AccessAPINoPage("bm/open/api/order/OrderSelfMention", jdParams, nil, nil, orderOperationResultParser)
	if err == nil {
		return utils.Interface2String(result), nil
	}
	return "", err
}

// 订单达达配送转商家自送接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=e7b4950164754eecac7ea87278c2b071
func (a *API) ModifySellerDelivery(orderId string, userName string) (detail string, err error) {
	jdParams := map[string]interface{}{
		"orderId":   orderId,
		"updatePin": utils.GetAPIOperator(userName),
	}
	result, err := a.AccessAPINoPage("order/modifySellerDelivery", jdParams, nil, nil, genNoPageResultParser("code", "msg", "detail", "0"))
	if err == nil {
		return utils.Interface2String(result), nil
	}
	return "", err
}

// 拣货完成且商家自送接口（这个接口是商家本身配置为自送模式下才能调用的接口，如果启用了达达配送，是不能调用的）
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=0e08e71a45dc48b6a337e06a852ac33a
func (a *API) OrderSerllerDelivery(orderId string, userName string) (detail string, err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"operator": utils.GetAPIOperator(userName),
	}
	result, err := a.AccessAPINoPage("bm/open/api/order/OrderSerllerDelivery", jdParams, nil, nil, orderOperationResultParser)
	if err == nil {
		return utils.Interface2String(result), nil
	}
	return "", err
}

// 商家自送，订单妥投接口
// https://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=ecc80f06d35141979f4841f345001f74
func (a *API) DeliveryEndOrder(orderId string, userName string) (result map[string]interface{}, err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"operPin":  utils.GetAPIOperator(userName),
		"operTime": utils.GetCurTimeStr(),
	}
	tmpResult, err := a.AccessAPINoPage("ocs/deliveryEndOrder", jdParams, nil, nil, nil)
	if err == nil {
		return tmpResult.(map[string]interface{}), nil
	}
	return nil, err
}

// 常规订单应结金额接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=17f0b596df554fe2b66fa7742a025d92
func (a *API) OrderShoudSettlementService(orderId string) (map[string]interface{}, error) {
	jdParams := map[string]interface{}{
		"orderId": orderId,
	}
	result, err := a.AccessAPINoPage("bill/orderShoudSettlementService", jdParams, nil, nil, genNoPageResultParser("code", "detail", "result", "0"))
	if err != nil {
		return nil, err
	}
	if result == nil {
		return nil, utils.NewErrorIntCode("查询订单信息异常", -4)
	}
	return result.(map[string]interface{}), nil
}

func (a *API) OrderShoudSettlementService2(orderId string) (orderSettlement *OrderSettlementInfo, err error) {
	result, err := a.OrderShoudSettlementService(orderId)
	if err == nil {
		err = JdMap2StructByJson(result, &orderSettlement, false)
	}
	return orderSettlement, err
}

// 查询售后单详情接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=170&apiid=6805ed690b7b4776b058067312c57d98
func (a *API) GetAfsService(orderId string) (map[string]interface{}, error) {
	jdParams := map[string]interface{}{
		"afsServiceOrder": orderId,
	}
	result, err := a.AccessAPINoPage("afs/getAfsService", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "0"))
	if err != nil {
		return nil, err
	}
	return result.(map[string]interface{}), nil
}

func (a *API) GetAfsService2(afsOrderID string) (afsOrderInfo *AfsServiceResponse, err error) {
	result, err := a.GetAfsService(afsOrderID)
	if err == nil {
		if err = JdMap2StructByJson(result, &afsOrderInfo, false); err != nil {
			baseapi.SugarLogger.Warnf("GetAfsService2, result:%s failed with error:%v", utils.Format4Output(result, true), err)
		}
	}
	return afsOrderInfo, err
}

// 商家审核用户取消申请接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=906b430307764a3ca3698c05c72f33d0
func (a *API) OrderCancelOperate(orderId string, isAgreed bool, operator, remark string) (err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"isAgreed": isAgreed,
		"operator": utils.GetAPIOperator(operator),
		"remark":   remark,
	}
	_, err = a.AccessAPINoPage("ocs/orderCancelOperate", jdParams, nil, nil, nullResultParser)
	return err
}

// 订单调整接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=a7378109fd7243eea9efbb6231a7401c
func (a *API) AdjustOrder(orderId, operPin, remark string, oaosAdjustDTOList []*OAOSAdjustDTO) (err error) {
	jdParams := map[string]interface{}{
		"orderId":           orderId,
		"operPin":           utils.GetAPIOperator(operPin),
		"remark":            remark,
		"oaosAdjustDTOList": oaosAdjustDTOList,
	}
	_, err = a.AccessAPINoPage("orderAdjust/adjustOrder", jdParams, nil, nil, genNoPageResultParser("code", "detail", "", "0"))
	return err
}

// 商家审核配送员取货失败接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=d10c63a2ea734b818b23f0bc1c8efe6f
func (a *API) ReceiveFailedAudit(orderId string, isAgreed bool, operator, remark string) (err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderId,
		"isAgreed": isAgreed,
		"operator": utils.GetAPIOperator(operator),
		"remark":   remark,
	}
	_, err = a.AccessAPINoPage("order/receiveFailedAudit", jdParams, nil, nil, nullResultParser)
	return err
}

// 催配送员抢单接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=96383a8274bd463a95dfc8b8d74220d1
func (a *API) UrgeDispatching(orderId, updatePin string) (err error) {
	jdParams := map[string]interface{}{
		"orderId":   orderId,
		"updatePin": utils.GetAPIOperator(updatePin),
	}
	_, err = a.AccessAPINoPage("bm/urgeDispatching", jdParams, nil, nil, nullResultParser)
	return err
}

// 商家确认收到拒收退回（或取消）的商品接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=21a55807c096410c9cac9b71e110fa43
func (a *API) ConfirmReceiveGoods(orderId string) (err error) {
	jdParams := map[string]interface{}{
		"orderId":     orderId,
		"operateTime": utils.GetCurTimeStr(),
	}
	_, err = a.AccessAPINoPage("order/confirmReceiveGoods", jdParams, nil, nil, nullResultParser)
	return err
}

// 订单取消且退款接口
// 自配送商家（或转自配送）的订单，由于无法完成订单配送，通过此接口取消订单并退款。
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=6be3f3a811f14f22a83007ab02f23b03
func (a *API) CancelAndRefund(orderId, operPin, operRemark string) (err error) {
	return fmt.Errorf("京东商家取消接口已下线,请APP联系客服或拨打客服热线:400 002 0020 取消订单")
	//if operRemark == "" {
	//	operRemark = "operRemark"
	//}
	//jdParams := map[string]interface{}{
	//	"orderId":    orderId,
	//	"operPin":    utils.GetAPIOperator(operPin),
	//	"operRemark": operRemark,
	//	"operTime":   utils.GetCurTimeStr(),
	//}
	//_, err = a.AccessAPINoPage("orderStatus/cancelAndRefund", jdParams, nil, nil, genNoPageResultParser("code", "detail", "", "0"))
	//return err
}

// 申请售后单审核接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=170&apiid=1690f6efc0144d59823b236e0d8506a1
func (a *API) AfsOpenApprove(afsOrderID string, afsApproveType int, rejectReason string, optPin string) (err error) {
	jdParams := map[string]interface{}{
		"serviceOrder": afsOrderID,
		"approveType":  afsApproveType,
		"optPin":       utils.GetAPIOperator(optPin),
	}
	if rejectReason != "" {
		jdParams["rejectReason"] = rejectReason
	}
	_, err = a.AccessAPINoPage("afs/afsOpenApprove", jdParams, nil, nil, nullResultParser)
	return err
}

// 售后单确认收货接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=170&apiid=4826086e81934405980ae26f80d956e0
func (a *API) ConfirmReceipt(afsOrderID, pin string) (err error) {
	jdParams := map[string]interface{}{
		"serviceOrder": afsOrderID,
		"pin":          utils.GetAPIOperator(pin),
	}
	_, err = a.AccessAPINoPage("afs/confirmReceipt", jdParams, nil, nil, nullResultParser)
	return err
}

// 商家自主发起售后接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=170&apiid=b8d1ddacb03846a8a2e78c79723c752f
func (a *API) AfsSubmit(OrderID, pin, questionTypeCode, questionDesc, questionPic, customerName, customerMobilePhone, address string, skuList []*VenderAfsSkuDTO) (afsOrderID string, err error) {
	jdParams := map[string]interface{}{
		"orderId":          OrderID,
		"pin":              utils.GetAPIOperator(pin),
		"questionTypeCode": questionTypeCode,
		"skuList":          skuList,
	}
	if questionDesc != "" {
		jdParams["questionDesc"] = questionDesc
	}
	if questionPic != "" {
		jdParams["questionPic"] = questionPic
	}
	if customerName != "" {
		jdParams["customerName"] = customerName
	}
	if customerMobilePhone != "" {
		jdParams["customerMobilePhone"] = customerMobilePhone
	}
	if address != "" {
		jdParams["address"] = address
	}
	result, err := a.AccessAPINoPage("afs/submit", jdParams, nil, nil, genNoPageResultParser("code", "msg", "result", "0"))
	if err == nil {
		afsOrderID = utils.Interface2String(result.(map[string]interface{})["serviceOrder"])
	}
	return afsOrderID, err
}

func ProcessQuestionPic(questionPic string) (outQuestionPic string) {
	const httpsPrefix = "https:"
	if questionPic != "" {
		picList := strings.Split(questionPic, ",")
		var picList2 []string
		for _, pic := range picList {
			baseURL := AfsPicPrefix
			pic2 := strings.ReplaceAll(pic, httpsPrefix, "")
			if pic2 != pic {
				baseURL = AfsPicPrefixHttps
			}
			if pic2 = utils.TrimBlankChar(pic2); pic2 != "" {
				picList2 = append(picList2, utils.GenerateGetURL(baseURL, pic2, nil))
			}
		}
		outQuestionPic = strings.Join(picList2, ",")
	}
	return outQuestionPic
}

// 订单商家加小费接口
// tips必须是100的倍数，另外必须要等到家下发运单后才能调用，否则会报“订单号srcOrderNo的订单不存在”错
// 这个tips是累计增的，比如第一次调用tips为100，再一次调用tips为200，则总共的tips就是300
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=ed9e3ca7325c4d4d8ceaf959ed0e7a62
func (a *API) OrderAddTips(orderID string, tips int, operator string) (err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderID,
		"tips":     tips,
		"operator": utils.GetAPIOperator(operator),
	}
	_, err = a.AccessAPINoPage("order/addTips", jdParams, nil, nil, nullResultParser)
	return err
}

// 根据订单号查询订单跟踪接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=d9d4fd73fba14fd8851a4c054d2ee42e
func (a *API) GetByOrderNoForOaos(orderNo string) (orderTrackList []*OrderTrack, err error) {
	jdParams := map[string]interface{}{
		"orderNo": orderNo,
	}
	result, err := a.AccessAPINoPage("orderTrace/getByOrderNoForOaos", jdParams, nil, nil, genNoPageResultParser("code", "msg", "orderTrackList", "0"))
	if err == nil {
		err = JdMap2StructByJson(result, &orderTrackList, false)
	}
	return orderTrackList, err
}

// 新版根据订单号查询订单跟踪接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=6450cd91dd5b4dc0bb6a6cd17af6d0a4
func (a *API) GetByOrderNoForOaosNew(orderID string) (orderTrackList []*OrderTrack, err error) {
	jdParams := map[string]interface{}{
		"orderId": orderID,
	}
	result, err := a.AccessAPINoPage("orderTrace/getByOrderNoForOaosNew", jdParams, nil, nil, genNoPageResultParser("code", "detail", "result", "0"))
	if err == nil {
		err = JdMap2StructByJson(result.(map[string]interface{})["orderTrackList"], &orderTrackList, false)
	}
	return orderTrackList, err
}

// 订单自提码核验接口
// https://openo2o.jddj.com/staticnew/widgets/resources.html?groupid=169&apiid=428fa2cb66784b64a85db36ec2972ff9
func (a *API) CheckSelfPickCode(selfPickCode, orderID, operPin string) (err error) {
	jdParams := map[string]interface{}{
		"selfPickCode": selfPickCode,
		"orderId":      orderID,
		"operPin":      operPin,
	}
	_, err = a.AccessAPINoPage("ocs/checkSelfPickCode", jdParams, nil, nil, nullResultParser)
	return err
}

type RefDiffAdjustSkuList struct {
	SkuId           string `json:"skuId"`
	SkuActualWeight int    `json:"skuActualWeight"`
}

// 生成退差价逆向单接口
//http://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=74ed627f2d2c45dbb804c900159e4c6a
func (a *API) GenerateReverseOrder(orderID string, skuList []*RefDiffAdjustSkuList) (err error) {
	jdParams := map[string]interface{}{
		"orderId":              orderID,
		"refDiffAdjustSkuList": skuList,
	}
	_, err = a.AccessAPINoPage("reverse/generateReverseOrder", jdParams, nil, nil, nullResultParser)
	return err
}

//商家投诉达达配送员
//http://opendj.jd.com/staticnew/widgets/resources.html?groupid=169&apiid=200ade433c834b14994c7151468276d2
func (a *API) ComplaintDadaDeliver(orderID string, resonID int) (err error) {
	jdParams := map[string]interface{}{
		"orderId":  orderID,
		"reasonId": resonID,
	}
	_, err = a.AccessAPINoPage("order/complaintDadaDeliverForPlatForm", jdParams, nil, nil, nullResultParser)
	return err
}
