package weimobapi

import (
	"crypto/md5"
	"fmt"
	"strings"
	"time"

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

const (
	MsgTopicOrder  = "ec_order"
	MsgTopicRights = "ec_rights"
)

const (
	MsgEventCreateOrder       = "createOrder"
	MsgEventOrderStatusChange = "orderStatusChange"

	MsgEventCreateRights   = "createRights"
	MsgEventCompleteRights = "completeRights"
	MsgEventCancelRights   = "cancelRights"
)

const (
	ChannelTypeWeixinOpen = 0
	ChannelTypeWeixinMini = 1
	ChannelTypeH5         = 2
	ChannelTypeQQ         = 3
	ChannelTypeWeibo      = 4
	ChannelTypeToutiao    = 5
	ChannelTypeAliPay     = 6
	ChannelTypeOffline    = 7
)

const (
	MsgOrderStatusWait4Pay       = 0 // 未支付
	MsgOrderStatusPartPayed      = 1 // 部分支付
	MsgOrderStatusPayed          = 2 // 已支付
	MsgOrderStatusCanDeliver     = 3 // 可发货
	MsgOrderStatusPartDelivering = 4 // 部分发货
	MsgOrderStatusDelivering     = 5 // 已发货
	MsgOrderStatusPartDelivered  = 6 // 部分确认收货
	MsgOrderStatusDelivered      = 7 // 确认收货
	MsgOrderStatusFinished       = 8 // 完成（不能再申请售后）
	MsgOrderStatusCancled        = 9 // 取消
)

type CallbackMsg struct {
	IsFake          bool   `json:"isFake"` // 是否自己生成的假消息
	ID              string `json:"id"`
	Topic           string `json:"topic"`
	Event           string `json:"event"`
	PublicAccountID string `json:"public_account_id"`
	BusinessID      string `json:"business_id"`
	Sign            string `json:"sign"`
	MsgSignature    string `json:"msgSignature"`

	StoreID     int64     `json:"storeId"`
	RightsID    int64     `json:"rightsId"`
	OrderNo     int64     `json:"orderNo"`
	StatusTime  time.Time `json:"statusTime"`
	ChannelType int       `json:"channelType"`

	MsgBody    map[string]interface{} `json:"msgBody"`
	MsgBodyStr string                 `json:"msg_body"`
}

type ErrorInfo struct {
	ErrCode int    `json:"errcode"`
	ErrMsg  string `json:"errmsg"`
}
type CallbackResponse struct {
	Code ErrorInfo `json:"code"`
}

var (
	SuccessResponse = &CallbackResponse{
		Code: ErrorInfo{
			ErrMsg: "success",
		},
	}
)

func Err2CallbackResponse(err error, data string) *CallbackResponse {
	if err == nil {
		return SuccessResponse
	}
	if data == "" {
		data = err.Error()
	}
	return &CallbackResponse{
		Code: ErrorInfo{
			ErrCode: -1,
			ErrMsg:  data,
		},
	}
}

func (a *API) CheckCallbackValidation(sign, msgSignature, id, msgBody string) bool {
	localSign := fmt.Sprintf("%x", md5.Sum([]byte(a.appID+id+a.appSecret)))
	// baseapi.SugarLogger.Debug(sign, ":", localSign)
	if localSign == sign {
		localSign := fmt.Sprintf("%x", md5.Sum([]byte(a.appID+id+msgBody+a.appSecret)))
		// baseapi.SugarLogger.Debug(msgSignature, ":", localSign)
		return localSign == msgSignature
	}
	return false
}

func (a *API) GetCallbackMsg(body []byte) (msg *CallbackMsg, callbackResponse *CallbackResponse) {
	err := utils.UnmarshalUseNumber(body, &msg)
	if err != nil {
		return nil, Err2CallbackResponse(err, "")
	}
	err = utils.UnmarshalUseNumber([]byte(msg.MsgBodyStr), &msg.MsgBody)
	if err != nil {
		return nil, Err2CallbackResponse(err, "")
	}
	msg.OrderNo = utils.MustInterface2Int64(msg.MsgBody["orderNo"])
	if !a.CheckCallbackValidation(msg.Sign, msg.MsgSignature, msg.ID, msg.MsgBodyStr) {
		return nil, Err2CallbackResponse(fmt.Errorf("sign is not match"), "")
	}
	if msg.Event == MsgEventCreateOrder {
		msg.StatusTime = utils.Str2Time(strings.Replace(msg.MsgBody["createTime"].(string), ": ", ":", -1))
		msg.ChannelType = int(utils.MustInterface2Int64(msg.MsgBody["channelType"]))
	} else {
		msg.StatusTime = time.Now()
		if msg.Topic == MsgTopicRights {
			msg.RightsID = utils.MustInterface2Int64(msg.MsgBody["rightsId"])
			msg.StoreID = utils.MustInterface2Int64(msg.MsgBody["storeId"])
		}
	}
	return msg, nil
}
