package mtpsapi

import (
	"net/http"
	"strings"

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

type CallbackResponse struct {
	Code int `json:"code"`
}

type CallbackCommonMsg struct {
	AppKey    string `json:"appkey"`
	Timestamp int64  `json:"timestamp"`
	Sign      string `json:"sign"`
}

type CallbackOrderMsg struct {
	OrderInfoCommon
	CallbackCommonMsg
	Status         int
	CancelReasonId int
	CancelReason   string
}

type CallbackOrderExceptionMsg struct {
	OrderInfoCommon
	CallbackCommonMsg
	ExceptionID    int64
	ExceptionCode  int
	ExceptionDescr string
	ExceptionTime  int64
}

type CallbackShopStatusMsg struct {
	ShopName      string `json:"shop_name"`
	ShopID        string `json:"shop_id"`
	Status        int    `json:"status"`
	RejectMessage string `json:"reject_message"`

	AppKey    string `json:"appkey"`
	Timestamp int64  `json:"timestamp"`
	Sign      string `json:"sign"`
}

var (
	SuccessResponse  = &CallbackResponse{Code: 0}
	SignatureIsNotOk = &CallbackResponse{Code: -1}
)

func Err2CallbackResponse(err error, data string) *CallbackResponse {
	if err == nil {
		return SuccessResponse
	}
	return &CallbackResponse{
		Code: -1,
	}
}

func (a *API) CheckCallbackValidation(request *http.Request) (callbackResponse *CallbackResponse) {
	err := request.ParseForm()
	if err == nil {
		sign := a.signParams(request.PostForm)
		if sign != request.FormValue(signKey) {
			baseapi.SugarLogger.Infof("Signature is not ok, mine:%v, get:%v", sign, request.FormValue(signKey))
			return SignatureIsNotOk
		}
		// for _, valueKey := range []string{"delivery_id", "mt_peisong_id", "order_id"} {
		// 	if request.FormValue(valueKey) == "" {
		// 		baseapi.SugarLogger.Errorf("Missing mandatory param PostForm:%v, valueKey:%v", request.PostForm, valueKey)
		// 		return &CallbackResponse{
		// 			Code: -1,
		// 		}
		// 	}
		// }
	} else {
		callbackResponse = Err2CallbackResponse(err, "")
	}
	return callbackResponse
}

func (a *API) GetOrderCallbackMsg(request *http.Request) (orderMsg *CallbackOrderMsg, callbackResponse *CallbackResponse) {
	if callbackResponse = a.CheckCallbackValidation(request); callbackResponse != nil {
		return nil, callbackResponse
	}
	orderMsg = &CallbackOrderMsg{
		OrderInfoCommon: OrderInfoCommon{
			DeliveryID:   utils.Str2Int64(request.FormValue("delivery_id")),
			MtPeisongID:  request.FormValue("mt_peisong_id"),
			OrderID:      strings.Trim(request.FormValue("order_id"), " \u00A0"),
			CourierName:  request.FormValue("courier_name"),
			CourierPhone: request.FormValue("courier_phone"),
		},
		CallbackCommonMsg: CallbackCommonMsg{
			AppKey:    request.FormValue("appkey"),
			Timestamp: utils.Str2Int64(request.FormValue("timestamp")),
			Sign:      request.FormValue("sign"),
		},
		Status:         int(utils.Str2Int64(request.FormValue("status"))),
		CancelReasonId: int(utils.Str2Int64WithDefault(request.FormValue("cancel_reason_id"), 0)),
		CancelReason:   request.FormValue("cancel_reason"),
	}
	return orderMsg, nil
}

func (a *API) GetOrderExceptionCallbackMsg(request *http.Request) (orderMsg *CallbackOrderExceptionMsg, callbackResponse *CallbackResponse) {
	if callbackResponse = a.CheckCallbackValidation(request); callbackResponse != nil {
		return nil, callbackResponse
	}
	orderMsg = &CallbackOrderExceptionMsg{
		OrderInfoCommon: OrderInfoCommon{
			DeliveryID:   utils.Str2Int64(request.FormValue("delivery_id")),
			MtPeisongID:  request.FormValue("mt_peisong_id"),
			OrderID:      strings.Trim(request.FormValue("order_id"), " \u00A0"),
			CourierName:  request.FormValue("courier_name"),
			CourierPhone: request.FormValue("courier_phone"),
		},
		CallbackCommonMsg: CallbackCommonMsg{
			AppKey:    request.FormValue("appkey"),
			Timestamp: utils.Str2Int64(request.FormValue("timestamp")),
			Sign:      request.FormValue("sign"),
		},
		ExceptionID:    utils.Str2Int64(request.FormValue("exception_id")),
		ExceptionCode:  int(utils.Str2Int64(request.FormValue("exception_code"))),
		ExceptionDescr: request.FormValue("exception_descr"),
		ExceptionTime:  utils.Str2Int64(request.FormValue("exception_time")),
	}
	return orderMsg, nil
}

func (a *API) GetShopStatusCallbackMsg(request *http.Request) (shopStatusMsg *CallbackShopStatusMsg, callbackResponse *CallbackResponse) {
	if callbackResponse = a.CheckCallbackValidation(request); callbackResponse != nil {
		return nil, callbackResponse
	}
	err := utils.Map2StructByJson(utils.URLValues2Map(request.PostForm), &shopStatusMsg, true)
	if err != nil {
		callbackResponse = Err2CallbackResponse(err, "")
	}
	return shopStatusMsg, callbackResponse
}
