package push

import (
	"bytes"
	"fmt"
	"net/url"
	"strings"
)

const (
	Sound          = "sound"
	SoundXM        = "sound_xm"
	SoundHW        = "sound_hw"
	SoundChannelXM = "sound_channel_xm"
	SoundChannelHW = "sound_channel_hw"
)

type Options struct {
	AppId           string
	AppKey          string
	AppSecret       string
	AppMasterSecret string
	ClientId        string
	ClientIds       []string

	MsgType  int //消息类型
	PushType int //推送类型

	Title               string
	Content             string
	Extra               interface{} //扩展数据  map[string]interface{}  key:"sound"  storein_voice.mp3
	TransmissionContent string      //透传内容

	//多厂家支持
	Intent string

	DebugModule bool
}
type Option func(o *Options)

//个推appId
func AppId(id string) Option {
	return func(o *Options) {
		o.AppId = id
	}
}

//个推appKey
func AppKey(key string) Option {
	return func(o *Options) {
		o.AppKey = key
	}
}

//个推appSecret
func AppSecret(secret string) Option {
	return func(o *Options) {
		o.AppSecret = secret
	}
}

//个推appMasterSecret
func AppMasterSecret(secret string) Option {
	return func(o *Options) {
		o.AppMasterSecret = secret
	}
}

//个推 app clientId
func ClientId(clientId string) Option {
	return func(o *Options) {
		o.ClientId = clientId
	}
}
func ClientIds(clientId []string) Option {
	return func(o *Options) {
		o.ClientIds = clientId
	}
}

//消息类型
func MsgType(msgType int) Option {
	return func(o *Options) {
		o.MsgType = msgType
	}
}

//推送类型
func PushType(pushType int) Option {
	return func(o *Options) {
		o.PushType = pushType
	}
}

//消息内容
func Title(title string) Option {
	return func(o *Options) {
		o.Title = title
	}
}
func Content(content string) Option {
	return func(o *Options) {
		o.Content = content
	}
}
func Extra(extra interface{}) Option {
	return func(o *Options) {
		o.Extra = extra
	}
}
func TransmissionContent(content string) Option {
	return func(o *Options) {
		o.TransmissionContent = content
	}
}
func Intent(intent string) Option {
	return func(o *Options) {
		o.Intent = intent
	}
}
func DebugModule(module bool) Option {
	return func(o *Options) {
		o.DebugModule = module
	}
}

func (o *Options) GetExt(key string) (value interface{}, ok bool) {
	var mapExt map[string]interface{}
	if mapExt, ok = o.Extra.(map[string]interface{}); !ok {
		return
	}
	if value, ok = mapExt[key]; ok {
		return
	}
	return
}

func (o *Options) FormatTranDataToIntent() string {
	tran, ok := o.GetExt("transData")
	if !ok {
		return o.Intent
	}
	var tranMap map[string]interface{}
	tranMap, ok = tran.(map[string]interface{})
	if !ok {
		return o.Intent
	}
	var params = bytes.NewBuffer(nil)
	for k, v := range tranMap {
		params.WriteString(fmt.Sprintf("S.%s=%v;", url.QueryEscape(k), url.QueryEscape(fmt.Sprintf("%v", v))))
	}
	if idx := strings.Index(o.Intent, "end"); idx > 0 {
		return o.Intent[0:idx] + params.String() + "end"
	}
	return o.Intent
}

const (
	Message = iota + 1
	Notification
)