package mtwmapi

import (
	"encoding/json"
	"errors"
	"fmt"
	"git.rosy.net.cn/baseapi/utils"
	"strings"
	"time"
)

const (
	MaxBatchPullPhoneNumberLimit = 1000
)

// http://developer.waimai.meituan.com/home/doc/food/99
const (
	OrderStatusUserCommitted = "1" // 用户已提交订单
	OrderStatusNew           = "2" // 向商家推送订单
	OrderStatusReceived      = "3" // 商家已收到
	OrderStatusAccepted      = "4" // 商家已确认
	OrderStatusDelivering    = "6" // 订单配送中
	OrderStatusDelivered     = "7" // 订单已送达
	OrderStatusFinished      = "8" // 订单已完成
	OrderStatusCanceled      = "9" // 订单已取消
)

const (
	WaybillStatusWait4Delivery  = "0"   // 配送单发往配送
	WaybillStatusPending        = "5"   // 配送压单
	WaybillStatusAccepted       = "10"  // 配送单已确认
	WaybillStatusCourierArrived = "15"  // 骑手已到店
	WaybillStatusPickedup       = "20"  // 骑手已取餐
	WaybillStatusDelivered      = "40"  // 骑手已送达
	WaybillStatusCanceled       = "100" // 配送单已取消
)

// APP方URL 推送用户或客服取消订单（必接）
const (
	CancelReasonAcceptTimeout        = 1001 // 系统取消，超时未确认
	CancelReasonPayTimeout           = 1002 // 系统取消，在线支付订单15分钟未支付
	CancelReasonPayCanceled          = 1101 // 用户取消，在线支付中取消
	CancelReasonCancelBeforeAccepted = 1102 // 用户取消，商家确认前取消
	CancelReasonRefundCanceled       = 1103 // 用户取消，用户退款取消
	CancelReasonWrongOrder           = 1201 // 客服取消，用户下错单
	CancelReasonUserTest             = 1202 // 客服取消，用户测试
	CancelReasonDuplicatedOrder      = 1203 // 客服取消，重复订单
	CancelReasonCSOther              = 1204 // 客服取消，其他原因
	CancelReasonOther                = 1301 // 其他原因
)

const (
	ResTypePending            = 0 // 未处理
	ResTypeMerchantRefused    = 1 // 商家驳回退款请求
	ResTypeMerchantAgreed     = 2 // 商家同意退款
	ResTypeCSRefused          = 3 // 客服驳回退款请求
	ResTypeCSAgreed           = 4 // 客服帮商家同意退款
	ResTypeTimeoutAutoAgreed  = 5 // 超过3小时自动同意
	ResTypeAutoAgreed         = 6 // 系统自动确认
	ResTypeUserCancelApply    = 7 // 用户取消退款申请
	ResTypeUserCancelComplain = 8 // 用户取消退款申诉
)

const (
	NotifyTypeApply                 = "apply"                 // 发起全款退款
	NotifyTypePartyApply            = "part"                  // 发起部分退款
	NotifyTypeSuccess               = "agree"                 // 确认退款
	NotifyTypeReject                = "reject"                // 驳回退款
	NotifyTypeCancelRefund          = "cancelRefund"          // 用户取消退款申请
	NotifyTypeCancelRefundComplaint = "cancelRefundComplaint" // 用户取消退款申诉
)

const (
	OrderPickTypeNormal = 0 // 普通(配送)
	OrderPickTypeSelf   = 1 // 用户到店自取
)

const (
	UserApplyCancelWaitMinute = 30 // 用户申请退款后，商家未在30分钟内（大连锁商家为3小时内）处理退款请求，系统将自动同意退款
)

const (
	RefundTypeAll  = 1
	RefundTypePart = 2
)

const (
	ExtrasPromotionTypeTaoCanZeng = 4 // 套餐赠
	ExtrasPromotionTypeManZeng    = 5 // 满赠

	ExtrasPromotionTypeTeJiaCai        = 7  // 特价菜
	ExtrasPromotionTypeZheKouCai       = 17 // 折扣菜
	ExtrasPromotionTypeSecondHalfPrice = 20 // 第2份半价活动
	ExtrasPromotionTypeShanGouBaoPin   = 56 // 闪购爆品
)

const (
	MaxGap4GetOrderIdByDaySeq = 100
)

type RefundSku struct {
	AppFoodCode  string  `json:"app_food_code"`
	SkuID        string  `json:"sku_id,omitempty"`
	Count        int     `json:"count"`
	ItemID       string  `json:"item_id,omitempty"`
	ActualWeight float64 `json:"actual_weight,omitempty"`
}

type RefundSkuDetail struct {
	AppFoodCode     string  `json:"app_food_code"`
	BoxNum          float64 `json:"box_num"`
	BoxPrice        float64 `json:"box_price"`
	Count           int     `json:"count"`
	FoodName        string  `json:"food_name"`
	FoodPrice       float64 `json:"food_price"`
	OriginFoodPrice float64 `json:"origin_food_price"`
	RefundPrice     float64 `json:"refund_price"`
	SkuID           string  `json:"sku_id"`
	Spec            string  `json:"spec"`
}

type RefundDetail struct {
	TotalFoodAmount       string `json:"total_food_amount"`
	BoxAmount             string `json:"box_amount"`
	ActivityPoiAmount     string `json:"activity_poi_amount"`
	ActivityMeituanAmount string `json:"activity_meituan_amount"`
	ActivityAgentAmount   string `json:"activity_agent_amount"`
	PlatformChargeFee     string `json:"platform_charge_fee"`
	SettleAmount          string `json:"settle_amount"`
	Productpreferences    string `json:"productpreferences"`
	NotProductpreferences string `json:"not_productpreferences"`
}

type RefundOrderDetail struct {
	ApplyReason                       string             `json:"apply_reason"`
	ApplyType                         int                `json:"apply_type"`
	CTime                             int64              `json:"ctime"`
	Money                             float64            `json:"money"`
	OrderID                           int64              `json:"order_id"`
	Pictures                          string             `json:"pictures"`
	PictureList                       []string           `json:"pictureList"`
	RefundType                        int                `json:"refund_type"`
	ResReason                         string             `json:"res_reason"`
	ResType                           int                `json:"res_type"`
	UTime                             int64              `json:"utime"`
	WmAppRetailForOrderPartRefundList []*RefundSkuDetail `json:"wmAppRetailForOrderPartRefundList"`
	WmOrderIDView                     int64              `json:"wm_order_id_view"`
	RefundPartialEstimateCharge       *RefundDetail      `json:"refund_partial_estimate_charge"`
}

type OrderExtraInfo struct {
	ActDetailID int     `json:"act_detail_id,omitempty"`
	MtCharge    float64 `json:"mt_charge,omitempty"`
	PoiCharge   float64 `json:"poi_charge,omitempty"`
	ReduceFee   float64 `json:"reduce_fee,omitempty"`
	Remark      string  `json:"remark,omitempty"`
	Type        int     `json:"type,omitempty"`

	RiderFee float64 `json:"rider_fee,omitempty"`
}

type FoodInfo struct {
	AppFoodCode  string  `json:"app_food_code"`
	BoxNum       float64 `json:"box_num"`
	BoxPrice     float64 `json:"box_price"`
	CartID       int     `json:"cart_id"`
	FoodDiscount float64 `json:"food_discount"`
	FoodName     string  `json:"food_name"`
	FoodProperty string  `json:"food_property"`
	Price        float64 `json:"price"`
	Quantity     int     `json:"quantity"`
	SkuID        string  `json:"sku_id"`
	Spec         string  `json:"spec"`
	Unit         string  `json:"unit"`
	Weight       int64   `json:"weight"`
}

type CanRefundFoodInfo struct {
	AppFoodCode        string  `json:"app_food_code"`
	BoxNum             float64 `json:"box_num"`
	BoxPrice           float64 `json:"box_price"`
	Count              int     `json:"count"`
	FoodName           string  `json:"food_name"`
	FoodPrice          float64 `json:"food_price"`
	IsRefundDifference int     `json:"is_refund_difference"`
	OriginFoodPrice    float64 `json:"origin_food_price"`
	RefundPrice        float64 `json:"refund_price"`
	SkuID              string  `json:"sku_id"`
}

type WmAppOrderActDetailInfo struct {
	ActID     int64   `json:"act_id"`
	Count     int     `json:"count"`
	MtCharge  float64 `json:"mtCharge"`
	PoiCharge float64 `json:"poiCharge"`
	Remark    string  `json:"remark"`
	Type      int     `json:"type"`
}

type SkuBenefitDetailInfo struct {
	ActivityPrice        float64                    `json:"activityPrice"`
	AppFoodCode          string                     `json:"app_food_code"`
	BoxNumber            float64                    `json:"boxNumber"`
	BoxPrice             float64                    `json:"boxPrice"`
	Count                int                        `json:"count"`
	Name                 string                     `json:"name"`
	OriginPrice          float64                    `json:"originPrice"`
	SkuID                string                     `json:"sku_id"`
	TotalActivityPrice   float64                    `json:"totalActivityPrice"`
	TotalBoxPrice        float64                    `json:"totalBoxPrice"`
	TotalMtCharge        float64                    `json:"totalMtCharge"`
	TotalOriginPrice     float64                    `json:"totalOriginPrice"`
	TotalPoiCharge       float64                    `json:"totalPoiCharge"`
	TotalReducePrice     float64                    `json:"totalReducePrice"`
	WmAppOrderActDetails []*WmAppOrderActDetailInfo `json:"wmAppOrderActDetails"`
}

type ActOrderChargeInfo struct {
	Comment     string `json:"comment"`
	FeeTypeDesc string `json:"feeTypeDesc"`
	FeeTypeID   int    `json:"feeTypeId"`
	MoneyCent   int64  `json:"moneyCent"`
}

type PoiReceiveDetailInfo struct {
	ActOrderChargeByMt      []*ActOrderChargeInfo `json:"actOrderChargeByMt"`
	ActOrderChargeByPoi     []*ActOrderChargeInfo `json:"actOrderChargeByPoi"`
	FoodShareFeeChargeByPoi int64                 `json:"foodShareFeeChargeByPoi"`
	LogisticsFee            int64                 `json:"logisticsFee"`
	OnlinePayment           int64                 `json:"onlinePayment"`
	WmPoiReceiveCent        int64                 `json:"wmPoiReceiveCent"`
}

type OrderInfo struct {
	AppOrderCode              string                  `json:"app_order_code"`
	AppPoiCode                string                  `json:"app_poi_code"`
	AvgSendTime               float64                 `json:"avg_send_time"`
	BackupRecipientPhone      string                  `json:"backup_recipient_phone"`
	Caution                   string                  `json:"caution"`
	CityID                    int                     `json:"city_id"`
	Ctime                     int64                   `json:"ctime"`
	DaySeq                    int                     `json:"day_seq"`
	DeliveryTime              int                     `json:"delivery_time"`
	Detail                    string                  `json:"detail"`
	DetailList                []*FoodInfo             `json:"detailList"`
	DinnersNumber             int                     `json:"dinners_number"`
	ExpectDeliverTime         int64                   `json:"expect_deliver_time"`
	Extras                    string                  `json:"extras"`
	ExtraList                 []*OrderExtraInfo       `json:"extraList"`
	HasInvoiced               int                     `json:"has_invoiced"`
	InvoiceTitle              string                  `json:"invoice_title"`
	IsFavorites               bool                    `json:"is_favorites"`
	IsPoiFirstOrder           bool                    `json:"is_poi_first_order"`
	IsPre                     int                     `json:"is_pre"`
	IsThirdShipping           int                     `json:"is_third_shipping"`
	Latitude                  float64                 `json:"latitude"`
	Longitude                 float64                 `json:"longitude"`
	LogisticsCancelTime       int64                   `json:"logistics_cancel_time"`
	LogisticsCode             string                  `json:"logistics_code"` // 此字段是配送方式变化后，不会改变
	LogisticsCompletedTime    int64                   `json:"logistics_completed_time"`
	LogisticsConfirmTime      int64                   `json:"logistics_confirm_time"`
	LogisticsDispatcherMobile string                  `json:"logistics_dispatcher_mobile"`
	LogisticsDispatcherName   string                  `json:"logistics_dispatcher_name"`
	LogisticsFetchTime        int64                   `json:"logistics_fetch_time"`
	LogisticsID               int                     `json:"logistics_id"`
	LogisticsName             string                  `json:"logistics_name"`
	LogisticsSendTime         int64                   `json:"logistics_send_time"`
	LogisticsStatus           int                     `json:"logistics_status"`
	OrderCompletedTime        int                     `json:"order_completed_time"`
	OrderConfirmTime          int                     `json:"order_confirm_time"`
	OrderID                   int64                   `json:"order_id"`
	OrderSendTime             int                     `json:"order_send_time"`
	OriginalPrice             float64                 `json:"original_price"`
	PackageBagMoney           int                     `json:"package_bag_money"`
	PayType                   int                     `json:"pay_type"`
	PickType                  int                     `json:"pick_type"`
	PoiReceiveDetail          string                  `json:"poi_receive_detail"`
	PoiReceiveDetailPtr       *PoiReceiveDetailInfo   `json:"poi_receive_detail_ptr"`
	RecipientAddress          string                  `json:"recipient_address"`
	RecipientName             string                  `json:"recipient_name"`
	RecipientPhone            string                  `json:"recipient_phone"`
	Remark                    string                  `json:"remark"`
	Result                    string                  `json:"result"`
	ShipperPhone              string                  `json:"shipper_phone"`
	ShippingFee               float64                 `json:"shipping_fee"`
	ShippingType              int                     `json:"shipping_type"`
	SkuBenefitDetail          string                  `json:"sku_benefit_detail"`
	SkuBenefitDetailList      []*SkuBenefitDetailInfo `json:"sku_benefit_detail_list"`
	SourceID                  int                     `json:"source_id"`
	Status                    int                     `json:"status"`
	TaxpayerID                string                  `json:"taxpayer_id"`
	Total                     float64                 `json:"total"`
	TotalWeight               int64                   `json:"total_weight"`
	Utime                     int64                   `json:"utime"`
	WmOrderIDView             int64                   `json:"wm_order_id_view"`
	WmPoiAddress              string                  `json:"wm_poi_address"`
	WmPoiID                   int                     `json:"wm_poi_id"`
	WmPoiName                 string                  `json:"wm_poi_name"`
	WmPoiPhone                string                  `json:"wm_poi_phone"`
}

type GetOrderActDetailParamAct struct {
	Type  int   `json:"type,omitempty"`
	ActID int64 `json:"act_id,omitempty"`
}

type GetOrderActDetailParam struct {
	OrderID  int64                        `json:"order_id_view"`
	ActParam []*GetOrderActDetailParamAct `json:"act_param,omitempty"`
}

type OrderActInfo struct {
	OrderID       int64 `json:"order_id_view"`
	ActDetailList []*struct {
		ActID         int64       `json:"act_id"`
		CouponDetail  interface{} `json:"coupon_detail"`
		EndTime       int64       `json:"end_time"`
		GiftsDetail   interface{} `json:"gifts_detail"`
		PoiDetail     interface{} `json:"poi_detail"`
		ProductDetail struct {
			AppFoodCode     string `json:"app_food_code"`
			CategorySeqence int    `json:"category_seqence"`
			Charge          string `json:"charge"`
			DayLimit        int    `json:"day_limit"`
			Name            string `json:"name"`
			OrderLimit      int    `json:"order_limit"`
			Period          string `json:"period"`
			Policy          string `json:"policy"`
			SettingType     int    `json:"setting_type"`
			UserType        int    `json:"user_type"`
			WeeksTime       string `json:"weeks_time"`
		} `json:"product_detail"`
		Remark    string `json:"remark"`
		StartTime int64  `json:"start_time"`
		Status    int    `json:"status"`
		Type      int    `json:"type"`
		TypeName  string `json:"type_name"`
	} `json:"act_detail_list"`
}

type GetOrderIdByDaySeqResult struct {
	Result   string  `json:"result"`
	OrderIDs []int64 `json:"order_ids"`
}

type UserRealPhoneNumberInfo struct {
	OrderID              int64  `json:"order_id"`
	AppPoiCode           string `json:"app_poi_code"`
	WmOrderIDView        string `json:"wm_order_id_view"`
	DaySeq               int    `json:"day_seq"`
	RealPhoneNumber      string `json:"real_phone_number"`       // 订单收货人的真实手机号码
	RealOrderPhoneNumber string `json:"real_order_phone_number"` // 鲜花绿植类订单预订人的真实手机号码，如无则返回空。
}

type RiderRealPhoneNumberInfo struct {
	OrderID              int64  `json:"order_id"`
	AppPoiCode           string `json:"app_poi_code"`
	WmOrderIDView        string `json:"wm_order_id_view"`
	RiderName            string `json:"rider_name"`
	RiderRealPhoneNumber string `json:"rider_real_phone_number"` // 骑手真实手机号
}

// GetRiderDeliveryPath 获取骑手坐标
type GetRiderDeliveryPath struct {
	//Code int64  `json:"code"`
	//Msg  string `json:"msg"`
	//Data []struct {
	Longitude int   `json:"longitude"`
	Latitude  int   `json:"latitude"`
	Time      int64 `json:"time"`
	//} `json:"data"`
}

// ReviewAfterSalesInfo 售后参数
type ReviewAfterSalesInfo struct {
	WmOrderIdView     int64  `json:"wm_order_id_view"`      // 订单展示ID
	RefundId          int64  `json:"refund_id"`             // 售后单ID
	ReviewType        int    `json:"review_type"`           // 0-同意退货；1-同意退款或同意仅退款无需退货；2-驳回退货/退款。
	RejectReasonCode  int    `json:"reject_reason_code"`    // 驳回code,当review_type=2必填
	RejectOtherReason string `json:"reject_other_reason"`   // 驳回原因说明,当reject_reason_code = -1 必填
	IsReturnGoods     int    `json:"is_return_goods"`       // 是否需要返货 0-不返货/1-返货 review_type=1时选填，不传默认为0，
	OutOfStockItemIds string `json:"out_of_stock_item_ids"` // 商品行item_id，多个item_id之间用逗号隔开，当订单有多个商品时
}

func (a *API) OrderReceived(orderID int64) (err error) {
	_, err = a.AccessAPI("order/poi_received", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	return err
}

func (a *API) OrderConfirm(orderID int64) (err error) {
	_, err = a.AccessAPI("order/confirm", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	return err
}

// 商家确认已完成拣货
// https://developer.waimai.meituan.com/home/docDetail/216
func (a *API) PreparationMealComplete(orderID int64) (err error) {
	params := map[string]interface{}{
		KeyOrderID: orderID,
	}
	_, err = a.AccessAPI("order/preparationMealComplete", true, params)
	return err
}

func (a *API) OrderCancel(orderID int64, cancelReason string, cancelReasonCode int) (err error) {
	_, err = a.AccessAPI("order/cancel", true, map[string]interface{}{
		KeyOrderID:    orderID,
		"reason":      cancelReason,
		"reason_code": cancelReasonCode,
	})
	return err
}

type MtwmOrderDelivering struct {
	Data string  `json:"data"`
	Err  *Errors `json:"err"`
}
type Errors struct {
	Code int64  `json:"code"`
	Msg  string `json:"msg"`
}

// 专快混配送转为商家自配送
// 预定单不能调用此接口
// https://developer.waimai.meituan.com/home/myquestionDetail/7382
func (a *API) OrderLogisticsChange2Self(orderID int64) (err error) {
	_, err = a.AccessAPI("order/logistics/change/poi_self", false, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err != nil && strings.Contains(err.Error(), "您的配送单已取消") {
		return nil
	}
	return err
}

// OrderDelivering 订单自配送中不支持骑手信息
func (a *API) OrderDelivering(orderID int64) (err error) {
	retval, err := a.AccessAPI("order/delivering", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err != nil {
		return err
	}
	if retval != nil {
		if retval.(string) == "ok" {
			return nil
		} else {
			return errors.New("美团系统操作异常,订单查询ng")
		}
	}
	return err
}

func (a *API) OrderArrived(orderID int64) (err error) {
	result, err := a.AccessAPI("order/arrived", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err != nil {
		return err
	}
	if result != nil {
		if result.(string) == "ok" {
			return nil
		} else {
			return errors.New("美团系统操作异常,订单查询ng")
		}
	}

	return err
}

// OrderRefundAgree 同意售后
func (a *API) OrderRefundAgree(orderID int64, reason string) (err error) {
	_, err = a.AccessAPI("order/refund/agree", true, map[string]interface{}{
		KeyOrderID: orderID,
		"reason":   reason,
	})
	return err
}

// OrderRefundReject 拒绝售后
func (a *API) OrderRefundReject(orderID int64, reason string) (err error) {
	_, err = a.AccessAPI("order/refund/reject", true, map[string]interface{}{
		KeyOrderID: orderID,
		"reason":   reason,
	})
	return err
}

// ReviewAfterSales 新版售后要求
func (a *API) ReviewAfterSales(param *ReviewAfterSalesInfo) (err error) {
	data, err := a.AccessAPI("ecommerce/order/reviewAfterSales", true, utils.Struct2MapByJson(param))
	fmt.Println(data)
	return err
}

func (a *API) OrderApplyPartRefund(orderID int64, reason string, removeSkuList []*RefundSku) (err error) {
	_, err = a.AccessAPI("order/applyPartRefund", false, map[string]interface{}{
		KeyOrderID:  orderID,
		"reason":    reason,
		"food_data": string(utils.MustMarshal(removeSkuList)),
	})
	return err
}

func (a *API) OrderViewStatus(orderID int64) (status int, err error) {
	result, err := a.AccessAPI("order/viewstatus", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err == nil {
		return int(utils.MustInterface2Int64(result.(map[string]interface{})["status"])), nil
	}
	return 0, err
}

func (a *API) OrderGetOrderDetail(orderID int64, isMTLogistics bool) (orderInfo map[string]interface{}, err error) {
	params := map[string]interface{}{
		KeyOrderID: orderID,
	}
	if isMTLogistics {
		params["is_mt_logistics"] = 1
	}
	result, err := a.AccessAPI("order/getOrderDetail", true, params)
	if err != nil {
		return nil, err
	}
	// 老是出现零号流水号订单,还不知道怎么生成的,这个地方直接掐断一下看看
	if int(utils.MustInterface2Int64(result.(map[string]interface{})["day_seq"])) == 0 {
		return nil, fmt.Errorf("订单流水号不能为0,%d", orderID)
	}
	return result.(map[string]interface{}), nil
}

func (a *API) OrderGetPartRefundFoods(orderID int64) (canRefundFoodList []*CanRefundFoodInfo, err error) {
	params := map[string]interface{}{
		KeyOrderID: orderID,
	}
	result, err := a.AccessAPI("order/getPartRefundFoods", true, params)
	if err == nil {
		err = utils.Map2StructByJson(result, &canRefundFoodList, false)
	}
	return canRefundFoodList, err
}

func (a *API) OrderLogisticsPush(orderID int64, reason string) (err error) {
	_, err = a.AccessAPI("order/logistics/push", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	return err
}

func (a *API) OrderLogisticsCancel(orderID int64, reason string) (err error) {
	_, err = a.AccessAPI("order/logistics/cancel", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	return err
}

// OrderLogisticsStatus 获取订单状态
func (a *API) OrderLogisticsStatus(orderID int64) (status *utils.RiderInfo, err error) {
	result, err := a.AccessAPI("order/logistics/status", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err != nil {
		return nil, err
	}

	logistics := &utils.RiderInfo{}
	data := result.(map[string]interface{})
	logistics.LogisticsStatus = int(utils.Interface2Int64WithDefault(data["logistics_status"], 0))
	logistics.CourierName = utils.Interface2String(data["dispatcher_name"])
	logistics.CourierPhone = utils.Interface2String(data["dispatcher_mobile"])
	return logistics, err
}

func (a *API) GetDeliveryPath(orderId int64, appPoiCode string) (lng, lat int, err error) {
	result, err := a.AccessAPI("order/getDeliveryPath", true, map[string]interface{}{
		KeyOrderID:    orderId,
		KeyAppPoiCode: appPoiCode,
	})
	if err != nil {
		return 0, 0, err
	}

	if result == nil {
		return 0, 0, nil
	}

	path, _ := json.Marshal(result)
	riderPath := make([]*GetRiderDeliveryPath, 0, 0)
	if err := json.Unmarshal(path, &riderPath); err != nil {
		return 0, 0, err
	}
	if len(riderPath) > 0 {
		return riderPath[len(riderPath)-1].Longitude, riderPath[len(riderPath)-1].Latitude, nil
	}
	return 0, 0, nil
}

// OrderLogisticsFee 获取订单配送费
func (a *API) OrderLogisticsFee(orderID int64) (payFee float64, err error) {
	result, err := a.AccessAPI("order/logistics/status", true, map[string]interface{}{
		KeyOrderID: orderID,
	})
	if err != nil {
		return 0, err
	}
	data := result.(map[string]interface{})
	// 美团运单,骑手确认订单之后取消的话就需要扣除全部的运单费用了,到店之后取消订单也不支付骑手配送费
	if utils.Interface2Int64WithDefault(data["logistics_status"], 0) == utils.Str2Int64WithDefault(WaybillStatusCanceled, 0) {
		if utils.Interface2Int64WithDefault(data["dispatcher_reach_poi_time"], 0) != 0 {
			return 2, nil
		} else if utils.Interface2Int64WithDefault(data["send_time"], 0) != 0 {
			return utils.TryInterface2Float64(data["pay_amount"])
		} else {
			return 0, nil
		}
	}
	return utils.TryInterface2Float64(data["pay_amount"])
}

// 拉取用户真实手机号（必接）
// https://developer.waimai.meituan.com/home/docDetail/222
// limit最大为MaxBatchPullPhoneNumberLimit = 1000
func (a *API) OrderBatchPullPhoneNumber(poiCode string, offset, limit int) (realNumberList []*UserRealPhoneNumberInfo, err error) {
	params := map[string]interface{}{
		"offset": offset,
		"limit":  limit,
	}
	if poiCode != "" {
		params[KeyAppPoiCode] = poiCode
	}
	result, err := a.AccessAPI("order/batchPullPhoneNumber", false, params)
	if err == nil {
		err = utils.Map2StructByJson(result, &realNumberList, false)
	}
	return realNumberList, err
}

// 拉取骑手真实手机号（必接），美团2019-09-17才开始灰度上线
// https://developer.waimai.meituan.com/home/docDetail/388
// limit最大为MaxBatchPullPhoneNumberLimit = 1000
func (a *API) OrderGetRiderInfoPhoneNumber(poiCode string, offset, limit int) (realNumberList []*RiderRealPhoneNumberInfo, err error) {
	params := map[string]interface{}{
		"offset": offset,
		"limit":  limit,
	}
	if poiCode != "" {
		params[KeyAppPoiCode] = poiCode
	}
	result, err := a.AccessAPI("order/getRiderInfoPhoneNumber", false, params)
	if err == nil {
		err = utils.Map2StructByJson(result, &realNumberList, false)
	}
	return realNumberList, err
}

// refundOrderDetailList不能定义为[]*RefundOrderDetail，否则会有解析错误，原因不明
func (a *API) GetOrderRefundDetail(orderID int64, refundType int) (refundOrderDetailList []*RefundOrderDetail, err error) {
	params := map[string]interface{}{
		"wm_order_id_view": orderID,
	}
	if refundType > 0 {
		params["refund_type"] = refundType
	}
	result, err := a.AccessAPI("ecommerce/order/getOrderRefundDetail", true, params)
	if err == nil {
		if err = utils.Map2StructByJson(result, &refundOrderDetailList, false); err == nil {
			for _, v := range refundOrderDetailList {
				if v.Pictures != "" {
					if err = utils.UnmarshalUseNumber([]byte(v.Pictures), &v.PictureList); err != nil {
						return nil, err
					}
				}
			}
		}
	}
	return refundOrderDetailList, err
}

func (a *API) GetOrderActDetail(queryData []*GetOrderActDetailParam) (orderActList []*OrderActInfo, err error) {
	params := map[string]interface{}{
		"query_data": string(utils.MustMarshal(queryData)),
	}
	result, err := a.AccessAPI("ecommerce/order/getOrderActDetail", true, params)
	if err == nil {
		err = utils.Map2StructByJson(result, &orderActList, false)
	}
	return orderActList, err
}

// 众包配送单追加小费
// https://developer.waimai.meituan.com/home/docDetail/158
func (a *API) OrderUpdateTip(orderID int64, tipAmount float64) (err error) {
	params := map[string]interface{}{
		KeyOrderID:   orderID,
		"tip_amount": tipAmount,
	}
	_, err = a.AccessAPI("order/zhongbao/update/tip", true, params)
	return err
}

// 美团外卖自配送商家同步发货状态和配送信息（推荐）
// https://waimaiopen.meituan.com/api/v1/ecommerce/order/logistics/sync
func (a *API) OrderStatusAndPsInfo(params map[string]interface{}) (err error) {
	delete(params, "opcode")            // 美团不需要此参数
	delete(params, "logistics_context") // 美团不需要此参数
	_, err = a.AccessAPI("ecommerce/order/logistics/sync", false, params)
	return err
}

// ApplyCompensation 取消的订单申请订单赔付
func (a *API) ApplyCompensation(param *ApplyCompensationRes) (err error) {
	_, err = a.AccessAPI2("order/applyCompensation", false, utils.Struct2MapByJson(param), resultKeySuccessMsg, "")
	return err
}

// 获取取消跑腿理由刘表
// https://open-shangou.meituan.com/home/docDetail/482
func (a *API) GetCancelDeliveryReason(orderId int64, appPoiCode string) (string, error) {
	data, err := a.AccessAPI("order/getCancelDeliveryReason", false, map[string]interface{}{"order_id": orderId, "app_poi_code": appPoiCode})
	if err != nil {
		return "", err
	}

	str, _ := json.Marshal(data)
	result := &DeliveryData{}
	if err := json.Unmarshal(str, result); err != nil {
		return "", err
	}

	list, _ := json.Marshal(&result.ReasonList)

	return string(list), nil
}

// 取消跑腿配送
func (a *API) CancelLogisticsByWmOrderId(reasonCode, detailContent, appPoiCode, orderId string) error {
	param := &CancelOrderParam{
		ReasonCode:    reasonCode,
		DetailContent: detailContent,
		AppPoiCode:    appPoiCode,
		OrderId:       orderId,
	}
	data, err := a.AccessAPI("order/cancelLogisticsByWmOrderId", false, utils.Struct2FlatMap(param))
	if err != nil {
		return err
	}

	result := &ResultMsg{}
	if err := json.Unmarshal([]byte(utils.Interface2String(data)), result); err != nil {
		return err
	}
	if result.Data != "ok" {
		return errors.New(result.Error.Msg)
	}
	return nil
}

// PushPrintMsg 推送订单打印消息,打印机打印时推送次消息
func (a *API) PushPrintMsg(orderId string) error {
	_, err := a.AccessAPI("ecommerce/poi/keyPointUpload", false, map[string]interface{}{
		"order_id": orderId,
		"op_type":  1,
	})
	return err
}

// EcommerceGetOrderIdByPage 批量获取门店订单号,下面三个被废弃(order/getOrderIdByDaySeq,ecommerce/order/getOrderIdByDaySeq,order/getOrderDaySeq)
func (a *API) EcommerceGetOrderIdByPage(poiCode string, startTime, endTime time.Time) ([]int64, error) {
	var (
		vernier     = ""
		orderIdList = make([]int64, 0, 0)
	)
	params := map[string]interface{}{
		KeyAppPoiCode: poiCode,
		"start_time":  startTime.Unix(),
		"end_time":    endTime.Unix(),
		"status_list": "1,2,4,8,9",
		"page_size":   100,
	}

	for {
		if vernier != "" {
			params["vernier"] = vernier
		}
		result, err := a.AccessAPI2("ecommerce/order/getOrderIdByPage", false, params, "", "")
		if err != nil {
			return nil, err
		}

		resultDate, err := json.Marshal(result)
		if err != nil {
			return nil, err
		}
		orderList := &EcommerceOrder{}
		if err := json.Unmarshal(resultDate, orderList); err != nil {
			return nil, err
		}

		for _, v := range orderList.SuccessList {
			orderIdList = append(orderIdList, v.OrderId)
		}

		if len(orderList.SuccessList) == 100 {
			vernier = orderList.SuccessMap.Vernier
		} else {
			return orderIdList, nil
		}
	}
}

// QuerySkuIsNeedUpc 查看商品是否需要填写upc
func (a *API) QuerySkuIsNeedUpc(tagId int) bool {
	data, err := a.AccessAPI2("retail/field/required/info", true, map[string]interface{}{"tag_id": tagId}, "success_map", "")
	if err != nil {
		return false
	}
	upc := data.(map[string]interface{})["upc"]
	upcCode := utils.Interface2Int64WithDefault(upc, 1)
	return upcCode == 0
}

// 去除多以属性
func CommonAttrValueUpdate(commonAttrValue string) string {
	commonAttrValueObj := make([]*CommonAttrValueList, 0, 0)
	if err := json.Unmarshal([]byte(commonAttrValue), &commonAttrValueObj); err != nil {
		return ""
	}

	result := make([]map[string]interface{}, 0, 0)
	for _, v := range commonAttrValueObj {
		commonAttrValueMap := utils.Struct2Map(v, "", false)
		delete(commonAttrValueMap, "setAttrId")
		delete(commonAttrValueMap, "setAttrName")
		delete(commonAttrValueMap, "setValueList")
		delete(commonAttrValueMap, "valueListSize")
		delete(commonAttrValueMap, "valueListIterator")
		result = append(result, commonAttrValueMap)
	}

	result2, _ := json.Marshal(result)
	return string(result2)
}

type CommonAttrValueList struct {
	AttrId    int    `json:"attrId"`
	AttrName  string `json:"attrName"`
	ValueList []struct {
		SetValue   bool   `json:"setValue"`
		SetValueId bool   `json:"setValueId"`
		Value      string `json:"value"`
		ValueId    int    `json:"valueId"`
	} `json:"valueList"`

	SetAttrId         bool `json:"setAttrId"`
	SetAttrName       bool `json:"setAttrName"`
	SetValueList      bool `json:"setValueList"`
	ValueListIterator []struct {
		Ref string `json:"$ref"`
	} `json:"valueListIterator"`
	ValueListSize int `json:"valueListSize"`
}

// GetOrderAddress 获取美团订单加密地址
// https://tscc.meituan.com/home/doc/market/10619
func (a *API) GetOrderAddress(orderId int64, reasonType int) (address string, err error) {
	result, err := a.AccessAPI2("ecommerce/order/getOrderRecipientAddress", true, map[string]interface{}{
		"order_id":    orderId,
		"reason_type": reasonType,
	}, "success_map", "")

	if err != nil {
		return "", err
	}

	return result.(map[string]interface{})["recipient_address"].(string), nil
}

// UploadMediaToOrder 订单上传图片,订单在骑手取货前且未超过订单预计送达时间时可以进行图片上传
func (a *API) UploadMediaToOrder(orderId string, images interface{}) error {
	byteData := utils.MustMarshal(images)
	_, err := a.AccessAPI2("ecommerce/order/uploadMedia", false, map[string]interface{}{"order_id": orderId, "media_list": string(byteData)}, "error_list", "")
	if err != nil {
		return err
	}
	return nil
}

type UploadMedia struct {
	Url              string `json:"url"`
	Type             int    `json:"type"`
	ConfigSnapshotId int64  `json:"configSnapshotId"`
	ItemId           int64  `json:"itemId"`
	Seq              int    `json:"seq"`
	InnerSeq         int    `json:"innerSeq"`
	RequireId        int64  `json:"requireId"`
	MediaCode        string `json:"mediaCode"`
}

//func (a *API) name() {
//	byteData := utils.MustMarshal(images)
//	_, err := a.AccessAPI2("retail/product/ruless", false, map[string]interface{}{"order_id": orderId, "media_list": string(byteData)}, "error_list", "")
//	if err != nil {
//		return err
//	}
//	return nil
//	retail / product / ruless
//}
