package request

import (
	"errors"
	"mtp20access/global"
	"mtp20access/res/pb"
	"regexp"
	"strings"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"go.uber.org/zap"
)

type MQNtfReq struct {
	Topic   string `json:"topic"`                      // 主题
	FunCode uint32 `json:"funCode" binding:"required"` // 功能码
	Data    string `json:"data" binding:"required"`    // 数据
}

// GetProtoBytes 将客户端请求的数据转换成总线使用的Protobuf
func (r *MQNtfReq) GetProtoBytes() (bytes *[]byte, err error) {
	// JSON -> Protobuf
	switch int(r.FunCode) {
	case global.THJPurchaseTradeNtf:
		m := pb.THJPurchaseTradeNtf{}
		if err = r.reflect(r.Data, &m); err != nil {
			return
		}
		if m.Header != nil {
			m.Header.RequestID = new(uint32)
			*m.Header.RequestID = 0
		} else {
			err = errors.New("请求信息序列化失败")
			return
		}
		if b, e := proto.Marshal(&m); e != nil {
			global.M2A_LOG.Error(e.Error(), zap.Error(e))
			err = errors.New("请求信息序列化失败")
			return
		} else {
			bytes = &b
		}
	case global.PurchaseTransferNtf:
		m := pb.PurchaseTransferNtf{}
		if err = r.reflect(r.Data, &m); err != nil {
			return
		}
		if m.Header != nil {
			m.Header.RequestID = new(uint32)
			*m.Header.RequestID = 0
		} else {
			err = errors.New("请求信息序列化失败")
			return
		}
		if b, e := proto.Marshal(&m); e != nil {
			global.M2A_LOG.Error(e.Error(), zap.Error(e))
			err = errors.New("请求信息序列化失败")
			return
		} else {
			bytes = &b
		}
	case global.WRTradeDealedNtf:
		m := pb.WRTradeDealedNtf{}
		if err = r.reflect(r.Data, &m); err != nil {
			return
		}
		if m.Header != nil {
			m.Header.RequestID = new(uint32)
			*m.Header.RequestID = 0
		} else {
			err = errors.New("请求信息序列化失败")
			return
		}
		if b, e := proto.Marshal(&m); e != nil {
			global.M2A_LOG.Error(e.Error(), zap.Error(e))
			err = errors.New("请求信息序列化失败")
			return
		} else {
			bytes = &b
		}
	}

	return
}

func (r *MQNtfReq) reflect(data string, m proto.Message) (err error) {
	// 由于JS对Long类型支持不佳，故让小程序端在使用单号时以字符串发过来，服务这边会自动把19位数字的字符串转化为数字
	reg, _ := regexp.Compile(`"[0-9]{19}"`)
	all := reg.FindAll([]byte(data), -1)
	for _, i := range all {
		r := strings.Replace(string(i), "\"", "", -1)
		data = strings.Replace(data, string(i), r, -1)
	}

	if e := jsonpb.UnmarshalString(data, m); e != nil {
		global.M2A_LOG.Error(e.Error(), zap.Error(e))
		err = errors.New("业务数据装箱失败")
		return
	}

	return
}
