package protocol

import (
	"encoding/json"
)

//CustomErrParse 解析自定义错误结构体
type CustomErrParse interface {
	ParseToMessage() *ResponseMessage
}

//ErrorMap 统一消息错误编码
type ErrorMap map[string]string

//Search 搜索错误描述
func (m ErrorMap) Search(code string) ErrorCode {
	if v, ok := m[code]; ok {
		return ErrorCode{
			Errno:  code,
			Errmsg: v,
		}
	}
	return ErrorCode{}
}

//ErrorCode 统一错误结构
type ErrorCode struct {
	Errno  string `json:"code"`
	Errmsg string `json:"msg"`
}

//ResponseMessage 统一返回消息结构体
type ResponseMessage struct {
	Errno  int         `json:"code"`
	Errmsg string      `json:"msg"`
	Data   interface{} `json:"data"`
}

func NewMesage(code string) *ResponseMessage {
	ecode := SearchErr(code)
	rsp := &ResponseMessage{
		Errno:  transformCode(ecode.Errno),
		Errmsg: ecode.Errmsg,
		Data:   nil,
	}
	return rsp
}

//ErrWithMessage  自定义错误结构
type ErrWithMessage struct {
	Err error `json:"-"`
	ErrorCode
}

var (
	_ CustomErrParse = new(ErrWithMessage)
	_ error          = new(ErrWithMessage)
)

//NewErrWithMessage 构建错误返回
//code:用于匹配统一消息错误编码 eRR:填充嵌套错误
func NewErrWithMessage(code string, eRR ...error) *ErrWithMessage {
	r := &ErrWithMessage{
		ErrorCode: SearchErr(code),
	}
	if len(eRR) > 0 {
		r.Err = eRR[0]
	}
	return r
}

//Error 实现接口error 中的方法
//将ErrorCode转为json数据,建议用于日志记录
func (e ErrWithMessage) Error() string {
	bt, _ := json.Marshal(e.ErrorCode)
	return string(bt)
}

//Unwrap 接口实现
func (e ErrWithMessage) Unwrap() error {
	return e.Err
}

//ParseToMessage 实现CustomErrParse的接口
func (e ErrWithMessage) ParseToMessage() *ResponseMessage {
	return NewMesage(e.Errno)
}

func SearchErr(code string) ErrorCode {
	return errmessge.Search(code)
}

//NewReturnResponse 控制层响应返回
func NewReturnResponse(data interface{}, eRR error) (msg *ResponseMessage) {
	//	var msg *ResponseMessage
	if eRR == nil {
		msg = NewMesage("0")
		msg.Data = data
		return msg
	}
	if x, ok := eRR.(CustomErrParse); ok {
		return x.ParseToMessage()
	}

	return NewMesage("1")
}

//BadRequestParam 控制层响应返回
func BadRequestParam(code string) *ResponseMessage {
	return NewMesage(code)
}

//NewPageDataResponse 控制层分页数据响应返回
func NewPageDataResponse(data interface{}, eRR error) (msg *ResponseMessage) {
	if eRR != nil {
		if x, ok := eRR.(CustomErrParse); ok {
			return x.ParseToMessage()
		}
		return NewMesage("1")
	}
	msg = NewMesage("0")
	msg.Data = map[string]interface{}{
		"gridResult": data,
	}
	return msg
}