package elmapi

import (
	"fmt"

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

// https://open.shop.ele.me/openapi/documents/callback
const (
	MsgTypeOrderValid        = 10
	MsgTypeOrderAccepted     = 12
	MsgTypeOrderCanceled     = 14
	MsgTypeOrderInvalid      = 15
	MsgTypeOrderForceInvalid = 17
	MsgTypeOrderFinished     = 18

	MsgTypeUserApplyCancel             = 20
	MsgTypeUserCancelApplyCancel       = 21
	MsgTypeMerchantRejectCancel        = 22
	MsgTypeMerchantAcceptCancel        = 23
	MsgTypeUserApplyArbitrateCancel    = 24
	MsgTypeCustomerServiceAcceptCancel = 25
	MsgTypeCustomerServiceRejectCancel = 26

	MsgTypeUserApplyRefund             = 30
	MsgTypeUserCancelRefund            = 31
	MsgTypeMerchantRejectRefund        = 32
	MsgTypeMerchantAcceptRefund        = 33
	MsgTypeUserApplyArbitrateRefund    = 34
	MsgTypeCustomerServiceAcceptRefund = 35
	MsgTypeCustomerServiceRejectRefund = 36

	MsgTypeUserUrgeOrder = 45

	MsgTypeWaybillWait4DeliveryVendor = 51
	MsgTypeWaybillWait4Courier        = 52
	MsgTypeWaybillPickingUp           = 53
	MsgTypeWaybillCourierArrived      = 54
	MsgTypeWaybillDelivering          = 55
	MsgTypeWaybillDelivered           = 56

	MsgTypeWaybillCanceledByMerchant         = 57
	MsgTypeWaybillCanceledByUser             = 58
	MsgTypeWaybillCanceledBySystem           = 59
	MsgTypeWaybillFailedCallLate             = 60
	MsgTypeWaybillFailedStore                = 61
	MsgTypeWaybillFailedMerchantInterrupt    = 62
	MsgTypeWaybillFailedCannotCantactUser    = 63
	MsgTypeWaybillFailedUserApplyRefund      = 64
	MsgTypeWaybillFailedWrongAddress         = 65
	MsgTypeWaybillFailedOutOfSerivceRange    = 66
	MsgTypeWaybillFailedCourierMarkException = 67
	MsgTypeWaybillFailedSystemMarkException  = 68
	MsgTypeWaybillFailedOtherException       = 69
	MsgTypeWaybillFailedTimeout              = 70

	MsgTypeDeiverBySelf                 = 71
	MsgTypeDontNeeded                   = 72
	MsgTypeRejectedOnlySupportPayOnline = 73
	MsgTypeRejectedOutOfServiceRange    = 74
	MsgTypeRejectedLateRequest          = 75
	MsgTypeRejectedSystemError          = 76
)

const (
	DeliveryStateToBeAssignedMerchant = "tobeAssignedMerchant"
	DeliveryStateToBeAssignedCourier  = "tobeAssignedCourier"
	DeliveryStateToBeFetched          = "tobeFetched"
	DeliveryStateDelivering           = "delivering"
	DeliveryStateCompleted            = "completed"
	DeliveryStateCancelled            = "cancelled"
	DeliveryStateException            = "exception"
	DeliveryStateArrived              = "arrived"
	DeliveryStateSelfDelivery         = "selfDelivery"
	DeliveryStateNoMoreDelivery       = "noMoreDelivery"
	DeliveryStateReject               = "reject"
)

type CallbackResponse struct {
	Message string `json:"message"`
}

type CallbackMsg struct {
	AppID     int    `json:"appId"`
	RequestID string `json:"requestId"`
	Type      int    `json:"type"`
	Message   string `json:"message"`
	ShopID    int    `json:"shopId"`
	Timestamp int64  `json:"timestamp"` // 毫秒
	UserID    int64  `json:"userId"`
	Signature string `json:"signature"`
}

type CallbackOrderStatusMsg struct {
	OrderID    string `json:"orderId"`
	State      string `json:"state"`
	ShopID     int    `json:"shopId"`
	UpdateTime int64  `json:"updateTime"` // 秒，文档上写的是毫秒，看示例数据应该是秒
	Role       int    `json:"role"`
	MsgType    int    `json:"-"` // 用于传递msg type，不是真正消息的一部分
}

type GoodItem struct {
	Name     string  `json:"name"`
	Quantity int     `json:"quantity"`
	Price    float64 `json:"price"`
	VfoodID  int64   `json:"vfoodiId"`
	SkuID    string  `json:"skuId"`
}

const (
	RefundTypeNormal = "normal"
	RefundTypePart   = "part"
)

type CallbackOrderCancelRefundMsg struct {
	OrderID      string     `json:"orderId"`
	RefundStatus string     `json:"refundStatus"`
	Reason       string     `json:"reason"`
	ShopID       int        `json:"shopId"`
	GoodsList    []GoodItem `json:"goodsList"`
	RefundType   string     `json:"refundType"`
	TotalPrice   float64    `json:"totalPrice"`
	UpdateTime   int64      `json:"updateTime"` // 秒
	MsgType      int        `json:"-"`          // 用于传递msg type，不是真正消息的一部分
}

type CallbackOrderUrgeMsg struct {
	OrderID    string `json:"orderId"`
	ShopID     int    `json:"shopId"`
	RemindID   int    `json:"remindId"`
	UserID     int64  `json:"userId"`
	UpdateTime int64  `json:"updateTime"` // 秒
	MsgType    int    `json:"-"`          // 用于传递msg type，不是真正消息的一部分
}

type CallbackWaybillStatusMsg struct {
	OrderID  string `json:"orderId"`
	ShopID   int    `json:"shopId"`
	State    string `json:"state"`
	SubState string `json:"subState"`
	Name     string `json:"name"`
	Phone    string `json:"phone"`
	UpdateAt int64  `json:"updateAt"` // 毫秒123
	MsgType  int    `json:"-"`        // 用于传递msg type，不是真正消息的一部分
}

var (
	SuccessResponse = &CallbackResponse{"ok"}
)

func Err2CallbackResponse(err error, data string) *CallbackResponse {
	if err == nil {
		return SuccessResponse
	}
	return &CallbackResponse{
		Message: fmt.Sprintf("error:%v, data:%v", err, data),
	}
}

func (a *API) unmarshalData(data []byte, msg interface{}) (callbackResponse *CallbackResponse) {
	err := utils.UnmarshalUseNumber(data, msg)
	if err != nil {
		return &CallbackResponse{
			Message: fmt.Sprintf(platformapi.ErrStrUnmarshalError, data, err),
		}
	}
	return nil
}

func (a *API) CheckCallbackValidation(mapData map[string]interface{}) (callbackResponse *CallbackResponse) {
	sign := a.signParamsMap(mapData, "")
	if remoteSign, _ := mapData[signKey].(string); sign != remoteSign {
		baseapi.SugarLogger.Infof("Signature is not ok, mine:%v, get:%v", sign, remoteSign)
		return &CallbackResponse{Message: platformapi.ErrStrCallbackSignatureIsWrong}
	}
	return nil
}

func (a *API) GetCallbackMsg(data []byte) (msg *CallbackMsg, callbackResponse *CallbackResponse) {
	msg = new(CallbackMsg)
	if callbackResponse = a.unmarshalData(data, msg); callbackResponse != nil {
		return nil, callbackResponse
	}

	mapData := utils.Struct2MapByJson(msg)
	callbackResponse = a.CheckCallbackValidation(mapData)
	return msg, callbackResponse
}
